Regex: Anzahl Zeichen aus Pattern ermitteln
-
Freitag, 2. März 2012 08:38Hallo 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
Alle Antworten
-
Freitag, 2. März 2012 14:21Moderator
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/
-
Montag, 5. März 2012 09:21Hallo 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
-
Montag, 5. März 2012 16:06Moderator
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 BreitenhoferMicrosoft Contingent Staff, Moderator Donnerstag, 8. März 2012 09:33
-
Mittwoch, 7. März 2012 08:33Hallo 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

