it-swarm.com.de

Abgleichen einer optionalen Teilzeichenfolge in einem regulären Ausdruck

Ich entwickle einen Algorithmus zum Parsen einer Zahl aus einer Reihe von kurzen Zeichenfolgen. Diese Saiten sind etwas regelmäßig, aber es gibt ein paar verschiedene allgemeine Formen und einige Ausnahmen. Ich versuche, eine Reihe von regulären Ausdrücken zu erstellen, die die verschiedenen Formen und Ausnahmen verarbeiten. Ich werde sie nacheinander anwenden, um zu sehen, ob ich eine Übereinstimmung erhalte.

Eine dieser Formen sieht ungefähr so ​​aus:

X (Y) Z

Woher:

  • X ist eine Zahl, die ich erfassen möchte.
  • Z ist statischer, vordefinierter Text. Es ist im Grunde genommen, wie ich feststelle, ob diese bestimmte Form anwendbar ist oder nicht.
  • Y ist eine Zeichenfolge unbekannter Länge und unbekannten Inhalts, die in Klammern eingeschlossen ist.

Auch: Y ist optional; Es wird nicht immer in einer Zeichenfolge mit Z und X angezeigt. Ich möchte also in der Lage sein, die Zahlen aus all diesen Zeichenfolgen zu extrahieren:

  • 10 Z
  • 20 (foo) Z
  • 30 (bar) Z

Im Moment habe ich einen regulären Ausdruck, der den ersten erfasst:

([0-9]+) +Z

Mein Problem ist, dass ich nicht weiß, wie ich einen regulären Ausdruck konstruieren soll, der genau dann mit einer Reihe von Zeichen übereinstimmt, wenn sie in Klammern eingeschlossen sind. Kann dies in einem einzigen regulären Ausdruck erfolgen?

38
Craig Walker
(\d+)\s+(\(.*?\))?\s?Z

Beachten Sie die geschützten Klammern und die Quantifizierer ? (Null oder einmalig). Jede der Gruppen, die Sie nicht erfassen möchten, kann eine Nichterfassungsgruppe sein (?:).

Ich stimme den Räumen zu. \s Ist dort eine bessere Option. Ich habe auch den Quantifizierer geändert, um sicherzustellen, dass es am Anfang Ziffern gibt. Was Zeilenumbrüche betrifft, hängt dies vom Kontext ab: Wenn die Datei zeilenweise analysiert wird, ist dies kein Problem. Eine andere Möglichkeit besteht darin, den Anfang und das Ende der Zeile zu verankern (fügen Sie am Anfang ein ^ Und am Ende ein $ Hinzu).

51
Godeke

Das sollte funktionieren:

^\d+\s?(\([^\)]+\)\s?)?Z$

Ich habe es zwar nicht getestet, aber ich gebe Ihnen die Aufschlüsselung. Wenn also noch Fehler vorhanden sind, sollte es ziemlich einfach sein, sie zu finden:

Zuerst der Anfang:

^ = beginning of string
\d+ = one or more decimal characters
\s? = one optional whitespace

Dann dieser Teil:

(\([^\)]+\)\s?)?

Ist eigentlich:

(.............)?

Womit die folgenden Inhalte nur dann optional sind, wenn sie vollständig vorhanden sind

\([^\)]+\)\s?

\( = an opening bracket
[^\)]+ = a series of at least one character that is not a closing bracket
\) = followed by a closing bracket
\s? = followed by one optional whitespace

Und das Ende besteht aus

Z$

Wo

Z = your constant string
$ = the end of the string
17
Martin Kool

Du kannst das:

([0-9]+) (\([^)]+\))? Z

Dies funktioniert jedoch nicht mit verschachtelten Parens für Y. Das Verschachteln erfordert eine Rekursion, die nicht mehr unbedingt regelmäßig (aber kontextfrei) ist. Moderne Regexp-Engines können damit umgehen, wenn auch mit einigen Schwierigkeiten (Rückverweise).

7
Konrad Rudolph

Versuche dies:

X (\(Y\))? Z
4
Kip