Benutzer mit den meisten Antworten
Regex: Anzahl Zeichen aus Pattern ermitteln

Frage
-
Hallo allerseits!In meiner Applikation habe ich diverse reguläre Ausdrücke wie "[0-9][0-9A-F]","[0-9]{6}" oder ".{30}". Allen Pattern ist es gemein, daß sie auf eine konstanteAnzahl von Zeichen matchen. Gibt es eine Möglichkeit diese Anzahl aus demPattern heraus zu ermitteln?TIAGrüßeThomas--Any problem in computer science can be solved with another layerof indirection. But that usually will create another problem.David Wheeler
Antworten
-
Also direkt ermitteln geht nicht, aber du kannst deinen ganzen ausdruck einklammern und dann folgendes anhängen: "|^{5}$". Also dann bspw. so hier:
"(?<VSTRA>[0-9][0-9A-F])|^{5}$"
Dabei wird überprüft ob zwischen Anfang (^) und Ende ($) 5 Zeichen liegen. Wenn ja, und dein Anderer Ausdruck vor "|" stimmt, dann gibt Regex.IsMatch(input, pattern); true zurück.
Hier sind noch die MSDN-Artikel zu Regex, Regex.IsMatch und den regulären Ausdrücken.
Koopakiller - http://koopakiller.ko.ohost.de/
- Als Antwort vorgeschlagen Robert BreitenhoferModerator Donnerstag, 8. März 2012 09:33
- Als Antwort markiert Tom Lambert (Koopakiller)Moderator Montag, 24. Juni 2013 14:35
Alle Antworten
-
Wieso brauchst du das? Ich würde einfach
if(MeinString.Length == 12) //bzw. if(MeinString.Length == 12 && Regex.IsMatch(MeinString, Pattern);
benutzen, die Pattern könnten dann ja eh nur die Zahl auf die richtigkeit überprüfen und ich glaub so gehts schneller ;)Koopakiller - http://koopakiller.ko.ohost.de/
-
Hallo Koopakiller!> Wieso brauchst du das?Ich hab's mir schon gedacht, daß diese Frage kommen wird ;-)Mein Programm soll Dateien auf formelle Korrektheit prüfen. Die einzelnen Zeilen dieser Datei haben dabei eine fixeLänge und entsprechen jeweils einem Datensatz. Es gibt ca. 15 verschiedene Datensatzarten, die wiederum aus bis zu25 Feldern mit fixer Länge bestehen.Für die Felddefinitionen hab' ich eine eigene Klasse mit Startposition, Länge und Regex-Pattern:class Field{public int Start { get; set; }public int Length { get; set; }public string Pattern { get; set; }}Für jede Satzart habe ich dann eine List von Felddefinitionen:List<Field> fields = new List<Field>();fields.Add(new Field() { Start = 1, Length = 2, Pattern = "(?<VSTRA>[0-9][0-9A-F])" });fields.Add(new Field() { Start = 3, Length = 1, Pattern = "(?<BLNDA>[1-9])" });fields.Add(new Field() { Start = 4, Length = 6, Pattern = "(?<VPNR>[0-9]{6})" });fields.Add(new Field() { Start = 10, Length = 2, Pattern = "(?<VPADR>[0-9]{2})" });...Aus diesen Felddefinitionen baue ich erst ein "Gesamt-Pattern" für die ganze Zeile und prüfe, ob diese entspricht.Falls nicht, extrahiere ich anhand von Start und Length Teilstrings aus der Zeile und prüfe sie gegen das jeweiligePattern.Langer Rede kurzer Sinn: ich möchte mir - wenns einfach geht - die explizite Angabe von Length sparen.GrüßeThomas--Any problem in computer science can be solved with another layerof indirection. But that usually will create another problem.David Wheeler
-
Also direkt ermitteln geht nicht, aber du kannst deinen ganzen ausdruck einklammern und dann folgendes anhängen: "|^{5}$". Also dann bspw. so hier:
"(?<VSTRA>[0-9][0-9A-F])|^{5}$"
Dabei wird überprüft ob zwischen Anfang (^) und Ende ($) 5 Zeichen liegen. Wenn ja, und dein Anderer Ausdruck vor "|" stimmt, dann gibt Regex.IsMatch(input, pattern); true zurück.
Hier sind noch die MSDN-Artikel zu Regex, Regex.IsMatch und den regulären Ausdrücken.
Koopakiller - http://koopakiller.ko.ohost.de/
- Als Antwort vorgeschlagen Robert BreitenhoferModerator Donnerstag, 8. März 2012 09:33
- Als Antwort markiert Tom Lambert (Koopakiller)Moderator Montag, 24. Juni 2013 14:35
-
Hallo Koopakiller!> Also direkt ermitteln geht nichtSchade. Trotzdem vielen Dank für Deine Mühe.> aber du kannst deinen ganzen ausdruck einklammern und dann folgendes anhängen: "|^{5}$".Das funktioniert nicht, weil ich ja bei der Prüfung aus mehreren Patterns ein gesamtes zusammenbaue und ^ bzw. $ janicht mitten in einem Pattern stehen dürfen. Der Vollständigkeit halber hier ein komplett lauffähiges Beispiel dessen,was ich mache:class Field{public int Start { get; set; }public int Length { get; set; }public string Pattern { get; set; }}class Parser{private List<Field> fields;private string fullPattern;public Parser(List<Field> fields){StringBuilder builder = new StringBuilder("^");foreach (Field field in fields){builder.Append(field.Pattern);}builder.Append("$");this.fullPattern = builder.ToString();this.fields = fields;}public void Parse(string line){Match match = Regex.Match(line, fullPattern);if (match.Success){Console.WriteLine("Satz OK");}else{foreach (Field field in this.fields){string part = line.Substring(field.Start - 1, field.Length);match = Regex.Match(part, field.Pattern);if (!match.Success){Console.WriteLine("'{0}' entspricht nicht {1}", part, field.Pattern);}}}}}class Program{static void Main(string[] args){List<Field> fields = new List<Field>();fields.Add(new Field() { Start = 1, Length = 2, Pattern = "(?<VSTRA>[0-9][0-9A-F])" });fields.Add(new Field() { Start = 3, Length = 1, Pattern = "(?<BLNDA>[1-9])" });fields.Add(new Field() { Start = 4, Length = 6, Pattern = "(?<VPNR>[0-9]{6})" });fields.Add(new Field() { Start = 10, Length = 2, Pattern = "(?<VPADR>[0-9]{2})" });Parser parser = new Parser(fields);string good = "1B796674999";string bad = "1B796cxb999";parser.Parse(good); // --> Satz OKparser.Parse(bad); // --> '96cxb9' entspricht nicht (?<VPNR>[0-9]{6})}}GrüßeThomas--Any problem in computer science can be solved with another layerof indirection. But that usually will create another problem.David Wheeler