Reguläre Ausdrücke werden im Wesentlichen zum Verarbeiten von Zeichenfolgen verwendet und sind sehr praktisch, um Zeichenfolgen abzugleichen, zu extrahieren und zu ersetzen.
Das Erlernen regulärer Ausdrücke ist jedoch immer noch etwas schwierig. Konzepte wie gieriges Matching, nicht gieriges Matching, erfassende Untergruppen und nicht erfassende Untergruppen sind nicht nur für Anfänger, sondern auch für viele Menschen, die mehrere Jahre gearbeitet haben, schwer zu verstehen.
Was ist also der beste Weg, reguläre Ausdrücke zu lernen? Wie beherrscht man reguläre Ausdrücke schnell?
Ich empfehle eine Möglichkeit, reguläre Regeln zu lernen, die ich für sehr gut halte: Lernen durch AST .
Das Abgleichsprinzip regulärer Ausdrücke besteht darin, die Musterzeichenfolge in AST zu analysieren und dann diesen AST zum Abgleichen mit der Zielzeichenfolge zu verwenden.
Verschiedene Informationen in der Musterzeichenfolge werden nach der Analyse im AST gespeichert. AST ist ein abstrakter Syntaxbaum, der nach einer grammatikalischen Struktur organisiert ist. Anhand der Struktur von AST können Sie die von regulären Ausdrücken unterstützte Syntax leicht erkennen.
Wie kann ich den AST eines regulären Ausdrucks anzeigen?
Sie können es visuell über die Website astexplorer.net betrachten:
Indem Sie die Analysesprache auf RegExp umstellen, können Sie den AST regulärer Ausdrücke visualisieren.
Wie bereits erwähnt, ist AST ein Baum, der nach Grammatik organisiert ist, sodass verschiedene Grammatiken leicht aus seiner Struktur heraussortiert werden können.
Dann lernen wir verschiedene Syntaxen aus der Perspektive von AST:
Beginnen wir mit der einfachen /abc/ Eine solche reguläre Syntax kann mit der Zeichenfolge „abc“ übereinstimmen, und ihr AST sieht so aus:
3 Zeichen, die Werte sind jeweils a, b, c, der Typ ist einfach. Der anschließende Abgleich besteht darin, den AST zu durchlaufen und jeweils diese drei Zeichen abzugleichen.
Wir haben es mit der Exec-API getestet:
Das 0. Element ist die übereinstimmende Zeichenfolge und index ist der Startindex der übereinstimmenden Zeichenfolge. Eingabe ist die Eingabezeichenfolge.
Versuchen wir es noch einmal mit Sonderzeichen:
/ddd/ bedeutet, dass drei Zahlen übereinstimmen. d ist ein Metazeichen (Metazeichen) mit besonderer Bedeutung, das von regulären Ausdrücken unterstützt wird.
Durch AST können wir auch erkennen, dass sie zwar ebenfalls Char sind, ihr Typ jedoch tatsächlich Meta ist:
Mit dem Metazeichen d kann jede Zahl abgeglichen werden:
Welche Metazeichen und welche einfache Zeichen sind, können Sie auf einen Blick über AST erkennen.
Regular unterstützt die Angabe eines Zeichensatzes über [], was bedeutet, dass er mit jedem der Zeichen übereinstimmen kann.
Aus AST können wir auch ersehen, dass es mit einer Ebene von CharacterClass umschlossen ist, was bedeutet, dass es sich um eine Zeichenklasse handelt, das heißt, es kann mit jedem darin enthaltenen Zeichen übereinstimmen.
Dies ist tatsächlich der Fall im Test:
Reguläre Ausdrücke unterstützen die Angabe, wie oft ein bestimmtes Zeichen wiederholt wird, unter Verwendung der Form {von, bis}.
Beispiel: /b{1,3}/ bedeutet, dass Zeichen b ein- bis dreimal wiederholt wird , /[abc ]{1,3}/ bedeutet, dass diese a/b/c-Zeichenklasse ein- bis dreimal wiederholt wird.
Wie aus AST hervorgeht, heißt diese Syntax Wiederholung:
Es verfügt über ein Quantifiziererattribut, das den Quantifizierer darstellt. Der Typ ist hier ein Bereich von 1 bis 3.
Reguläre Ausdrücke unterstützen auch die Abkürzungen einiger Quantoren, z. B. + für 1 bis unzählige Male, * für 0 bis unzählige Male und ? für 0 oder 1 Mal.
Es handelt sich um verschiedene Arten von Quantoren:
Einige Studenten fragen sich vielleicht: Was bedeutet das Attribut „Gier“ hier?
Greedy bedeutet gierig. Dieses Attribut gibt an, ob es sich bei dieser Wiederholung um eine gierige Übereinstimmung oder eine nicht gierige Übereinstimmung handelt.
Wenn Sie nach dem Quantifizierer ein ? hinzufügen, werden Sie feststellen, dass Greedy zu False wird, was bedeutet, dass auf Non-Greed-Matching umgestellt wird:
Was bedeuten also gierig und nicht gierig?
Sehen wir uns ein Beispiel an.
Der standardmäßige Wiederholungsabgleich ist gierig und wird weiterhin abgeglichen, solange die Bedingungen erfüllt sind, sodass acbac hier abgeglichen werden kann.
Hinzufügen eines ?, nachdem der Quantifizierer auf „nicht gierig“ umgeschaltet wurde, und nur der erste wird abgeglichen:
Dies ist ein gieriges Matching und ein nicht gieriges Matching. Wir können klar erkennen , dass gierige und nicht gierige Übereinstimmungen für die wiederholte Grammatik gelten. Fügen Sie nach dem Quantifizierer ein ? hinzu.
Der reguläre Ausdruckunterstützt das Einfügen eines Teils der übereinstimmenden Zeichenfolge in eine Untergruppe und die Rückgabe über ().
Schauen Sie sich das AST an:
Der entsprechende AST heißt Gruppe.
Und Sie werden feststellen, dass es ein Erfassungsattribut hat, das standardmäßig auf „true“ gesetzt ist:
Was bedeutet das?
Dies ist die Syntax für die Untergruppenerfassung.
Wenn Sie keine Untergruppen erfassen möchten, können Sie so schreiben (?:aaa)
Schauen Sie, die Erfassung ist falsch geworden.
Was ist der Unterschied zwischen Capture und Non-Capture?
Probieren wir es aus:
Oh, es stellt sich heraus, dass das Erfassungsattribut der Gruppe angibt, ob extrahiert werden soll oder nicht.
Aus dem AST können wir ersehen , dass die Erfassung für Untergruppen erfolgt. Der Standardwert ist „Erfassung“, was bedeutet, dass der Inhalt der Untergruppe über ?: extrahiert wird und der Inhalt der Untergruppe nicht extrahiert wird.
Wir sind bereits mit der Verwendung von AST zum Verständnis der regulären Syntax vertraut, aber schauen wir uns etwas etwas Schwierigeres an:
Reguläre Ausdrücke unterstützen den Ausdruck von Look-Ahead-Behauptungen durch die Syntax von (?=xxx), Dies wird verwendet, um ein bestimmtes Zeichen zu beurteilen. Ob der Zeichenfolge eine bestimmte Zeichenfolge vorangestellt ist.
Durch AST können Sie sehen, dass diese Syntax Assertion heißt und der Typ Lookahead ist, was bedeutet, dass er nach vorne schaut und nur mit der vorherigen Bedeutung übereinstimmt:
Was bedeutet das? Warum schreibst du das? Was ist der Unterschied zwischen /bbb(ccc)/ und /bbb(?:ccc)/?
Probieren wir es aus:
Aus den Ergebnissen ist ersichtlich:
/bbb(ccc)/ stimmt mit der Untergruppe von ccc überein und extrahiert diese Untergruppe, da die Standarduntergruppe erfasst wird.
/bbb(?:ccc)/ entspricht der Untergruppe von ccc, wird jedoch nicht extrahiert, da wir die Untergruppe so eingestellt haben, dass sie nicht über ?: erfasst wird.
/bbb(?=ccc)/ Die mit ccc übereinstimmende Untergruppe wird nicht extrahiert, was darauf hinweist, dass sie ebenfalls nicht erfasst wird. Der Unterschied zwischen it und ?: besteht darin, dass ccc nicht im Matching-Ergebnis erscheint.
Dies ist die Natur einer Lookahead-Behauptung: Eine Lookahead-Behauptung bedeutet, dass einer bestimmten Zeichenfolge eine bestimmte Zeichenfolge vorangestellt ist, die entsprechende Untergruppe nicht erfasst wird und die bestätigte Zeichenfolge nicht im Übereinstimmungsergebnis erscheint.
Wenn diese Zeichenfolge nicht folgt, findet keine Übereinstimmung statt:
Ändern Sie ?= in ?! Dann ändert sich die Bedeutung durch AST:
Obwohl die Lookahead-Behauptung immer noch zuerst geltend gemacht wird, gibt es ein zusätzliches negatives Attribut von true.
Die Bedeutung ist offensichtlich. Ursprünglich bedeutet dies, dass die Vorderseite eine bestimmte Zeichenfolge ist. Nach der Negation bedeutet dies, dass die Vorderseite keine bestimmte Zeichenfolge ist.
Dann ist das Matching-Ergebnis genau das Gegenteil:
Jetzt stimmt es nur dann überein, wenn davor keine bestimmte Zeichenfolge steht. Dies ist eine negative Lookahead-Behauptung.
Wenn es eine vorhergehende Behauptung gibt, gibt es natürlich eine nachfolgende Behauptung, das heißt, sie stimmt nur überein, wenn ihr eine bestimmte Zeichenfolge folgt.
Ebenso kann es auch verneint werden:
Man kann sich leicht den AST entsprechend (?<=aaa) vorstellen, bei dem es sich um eine Lookbehind-Behauptung handelt:
Der AST, der (?<!aaa) entspricht, besteht darin, ein negatives Attribut hinzuzufügen:
Look-Ahead-Assertion und Look-Behind-Assertion sind die am schwierigsten zu verstehende Syntax für reguläre Ausdrücke. Ist es viel einfacher, sie durch AST zu verstehen?
Reguläre Ausdrücke sind ein sehr praktisches Werkzeug zum Verarbeiten von Zeichenfolgen, aber es ist immer noch etwas schwer zu erlernen Viele Menschen sind verwirrt über Syntax wie gieriges Matching, nicht gieriges Matching, erfassende Untergruppen, nicht erfassende Untergruppen, Lookahead-Behauptungen, Lookbehind-Behauptungen usw.
Ich empfehle, reguläre Regeln über AST zu lernen. AST ist ein nach grammatikalischer Struktur organisierter Objektbaum, der durch die Namen und Attribute von AST-Knoten leicht verdeutlicht werden kann.
Zum Beispiel haben wir durch AST klargestellt:
Die Wiederholungssyntax (Wiederholung) besteht aus Zeichen + Quantifizierer. Die Standardeinstellung ist Greedy Matching (Greedy ist wahr), was bedeutet, dass nach dem Quantifizierer kein Matching hinzugefügt wird -Gieriger Abgleich, stoppt, wenn ein Zeichen übereinstimmt.
Die Untergruppensyntax (Gruppe) wird zum Extrahieren einer bestimmten Zeichenfolge verwendet. Die Standardeinstellung ist die Erfassung (Erfassung ist wahr), was bedeutet, dass eine Extraktion erforderlich ist (?:xxx), die nur übereinstimmt, aber nicht extrahiert .
Die Assertionssyntax (Assertion) stellt eine bestimmte Zeichenfolge davor oder danach dar. Sie ist in Lookahead-Assertion und (?<=xxx) unterteilt, um sie auszudrücken Negation (negativ ist wahr), was genau das Gegenteil bedeutet.
Ist es das tiefe Verständnis der Syntax in verschiedenen Dokumenten oder das tiefe Verständnis der Syntax im Compiler?
Kein Grund zu fragen, es muss der Compiler sein!
Dann ist es natürlich besser, die Grammatik anhand des Syntaxbaums zu lernen, der anhand der Grammatik analysiert wird, als anhand des Dokuments.
Dies gilt für reguläre Ausdrücke und auch für das Erlernen anderer Grammatiken. Wenn Sie die Grammatik mit AST lernen können, müssen Sie die Dokumentation nicht lesen.