Suche…


Parameter

Quantifizierer Beschreibung
? Passen Sie das vorangehende Zeichen oder den Unterausdruck 0 oder 1 Mal an (vorzugsweise 1).
* Stimmt mit dem vorhergehenden Zeichen oder Unterausdruck mindestens 0 mal überein (so viele wie möglich).
+ Ordnen Sie den vorhergehenden Buchstaben oder Unterausdruck mindestens ein Mal (so viele wie möglich) zu.
{n} Passen Sie das vorhergehende Zeichen oder den Unterausdruck genau n- mal an.
{min,} Entspricht die vorangehenden Zeichen oder subexpression min oder mehrmals (so viele wie möglich).
{0,max} Passen Sie das vorhergehende Zeichen oder den untergeordneten Ausdruck maximal oder weniger oft an (so nahe wie möglich an das Maximum ).
{min,max} Passen Sie den vorhergehenden Buchstaben oder Unterausdruck mindestens min , jedoch nicht mehr als max. An (so nahe wie möglich an max ).
Faule Quantifizierer Beschreibung
?? Passen Sie das vorangehende Zeichen oder den Unterausdruck 0 oder 1 Mal an (vorzugsweise 0).
*? Stimmt mit dem vorhergehenden Zeichen oder Unterausdruck mindestens 0 mal überein (so wenig wie möglich).
+? Ordnen Sie den vorhergehenden Buchstaben oder Unterausdruck mindestens ein Mal (so wenig wie möglich) zu.
{n}? Passen Sie das vorhergehende Zeichen oder den Unterausdruck genau n- mal an. Kein Unterschied zwischen gieriger und fauler Version.
{min,}? Entspricht die vorhergehenden Zeichen oder subexpression min oder mehrmals (so nahe wie möglich min).
{0,max}? Passen Sie das vorhergehende Zeichen oder den untergeordneten Ausdruck maximal oder seltener an (so wenig wie möglich).
{min,max}? Passen Sie den vorhergehenden Buchstaben oder Unterausdruck mindestens min , jedoch nicht mehr als max (möglichst nahe an min ) an.

Bemerkungen

Gier

Ein gieriger Quantifizierer versucht immer, das Untermuster so oft wie möglich zu wiederholen, bevor er durch Backtracking kürzere Übereinstimmungen untersucht.

Im Allgemeinen entspricht ein gieriges Muster der längsten möglichen Zeichenfolge.

Standardmäßig sind alle Quantifizierer gierig.

Faulheit

Ein faule (auch nicht-gierig oder nur ungern genannt) quantifier immer versucht , das Untermuster so wenig wie möglich zu wiederholen, vor längeres Matches durch Expansion zu erkunden.

Im Allgemeinen entspricht ein Lazy-Pattern der kürzesten möglichen Zeichenfolge.

Um Quantifikatoren faul zu machen, einfach anhängen ? zu dem vorhandenen Quantifizierer, z. B. +? {0,5}? .

Das Konzept von Gier und Faulheit existiert nur in rückverfolgbaren Motoren

Die Vorstellung von gierigen / faulen Quantifizierern existiert nur in Regex-Engines. In Regex-Engines ohne Backtracking oder POSIX-kompatiblen Regex-Engines geben die Quantifizierer nur die Ober- und Untergrenze der Wiederholung an, ohne anzugeben, wie die Übereinstimmung gefunden werden soll.

Gierigkeit gegen Faulheit

Gegeben die folgende Eingabe:

aaaaaAlazyZgreeedyAlaaazyZaaaaa

Wir werden zwei Muster verwenden: eines gierig: A.*Z und eines faul: A.*?Z Diese Muster ergeben folgende Übereinstimmungen:

  • A.*Z ergibt 1 Treffer: AlazyZgreeedyAlaaazyZ (Beispiele: Regex101 , Rubular )
  • A.*?Z ergibt 2 Treffer: AlazyZ und AlaaazyZ (Beispiele: Regex101 , Rubular )

Konzentriere dich zuerst auf das, was A.*Z macht. Wenn es mit dem ersten A übereinstimmt, versucht das .* , Gierig zu sein, dann so viele zu finden . wie möglich.

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \________________________/
      A.* matched, Z can't match

Da das Z nicht übereinstimmt, zieht sich die Engine zurück, und .* Muss dann um eins geringer sein . :

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \_______________________/
      A.* matched, Z can't match

Das passiert noch ein paar Mal, bis es endlich so weit ist:

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \__________________/
      A.* matched, Z can now match

Jetzt kann Z passen, also stimmt das Gesamtmuster überein:

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \___________________/
      A.*Z matched

Im Gegensatz dazu trifft die widerwillige (faule) Wiederholung in A.*?Z zunächst auf wenige . wie möglich und dann mehr nehmen . wie nötig. Dies erklärt, warum es zwei Übereinstimmungen in der Eingabe findet.

Hier ist eine visuelle Darstellung der Übereinstimmung der beiden Muster:

aaaaaAlazyZgreeedyAlaaazyZaaaaa
     \____/l      \______/l      l = lazy
     \_________g_________/       g = greedy

Beispiel basierend auf einer Antwort von Polygenschmiermitteln .

Der POSIX-Standard enthält nicht das ? Betreiber, so dass viele POSIX-Regex-Engines nicht faul passen. Während das Refactoring, vor allem mit dem "größten Trick aller Zeiten" , in manchen Fällen zum Vergleich beitragen kann, besteht die einzige Möglichkeit, ein echtes Lazy-Matching zu haben, in der Verwendung einer Engine, die dies unterstützt.

Grenzen mit mehreren Übereinstimmungen

Wenn Sie eine Eingabe mit genau definierten Grenzen haben und mehr als eine Übereinstimmung in Ihrer Zeichenfolge erwarten, haben Sie zwei Möglichkeiten:

  • Verwendung fauler Quantifizierer;
  • Verwendung einer negierten Zeichenklasse

Folgendes berücksichtigen:

Sie haben eine einfache Template-Engine, Sie möchten Teilzeichenfolgen wie $[foo] ersetzen, wobei foo eine beliebige Zeichenfolge sein kann. Sie möchten diese Teilzeichenfolge durch das ersetzen, das auf dem Teil zwischen den [] basiert.

Sie können etwas wie \$\[(.*)\] Versuchen und dann die erste Capture-Gruppe verwenden.

Das Problem dabei ist, wenn Sie eine Zeichenfolge wie something $[foo] lalala $[bar] something else ist

something $[foo] lalala $[bar] something else
          | \______CG1______/|
          \_______Match______/

Die Erfassungsgruppe ist foo] lalala $[bar die möglicherweise nicht gültig ist.

Sie haben zwei Lösungen

  1. Faulheit verwenden: In diesem Fall ist das * Faulenzen eine Möglichkeit, die richtigen Dinge zu finden. Sie ändern also Ihren Ausdruck in \$\[(.*?)\]

  2. Bei Verwendung einer negierten Zeichenklasse: [^\]] ändern Sie Ihren Ausdruck in \$\[([^\]]*)\] .

In beiden Lösungen ist das Ergebnis das gleiche:

something $[foo] lalala $[bar] something else
          | \_/|        | \_/|
          \____/        \____/

Die Capture-Gruppe ist jeweils foo und bar .


Die Verwendung einer negierten Zeichenklasse reduziert das Backtracking-Problem und kann Ihre CPU bei großen Eingaben viel Zeit sparen.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow