JavaRush /Java-Blog /Random-DE /RegEx: 20 kurze Schritte zur Beherrschung regulärer Ausdr...
Artur
Level 40
Tallinn

RegEx: 20 kurze Schritte zur Beherrschung regulärer Ausdrücke. Teil 4

Veröffentlicht in der Gruppe Random-DE
RegEx: 20 kurze Schritte zur Beherrschung regulärer Ausdrücke. Teil 1 RegEx: 20 kurze Schritte zur Beherrschung regulärer Ausdrücke. Teil 2 20 kurze Schritte zur Beherrschung regulärer Ausdrücke. Teil 3 In diesem letzten Teil in der Mitte geht es um Dinge, die hauptsächlich von Meistern regulärer Ausdrücke verwendet werden. Aber der Stoff aus den vorherigen Teilen war doch einfach für dich, oder? Das bedeutet, dass Sie mit diesem Material genauso problemlos umgehen können! Original hier RegEx: 20 kurze Schritte zur Beherrschung regulärer Ausdrücke.  Teil 4 - 1 <h2>Schritt 16: Gruppen ohne Erfassung (?:)</h2> RegEx: 20 kurze Schritte zur Beherrschung regulärer Ausdrücke.  Teil 4 - 2In den beiden Beispielen im vorherigen Schritt haben wir Text erfasst, den wir nicht wirklich brauchten. Bei der Aufgabe „Dateigrößen“ haben wir die Leerzeichen vor der ersten Ziffer der Dateigrößen erfasst, und bei der Aufgabe „CSV“ haben wir die Kommas zwischen den einzelnen Token erfasst. Wir müssen diese Zeichen nicht erfassen, aber wir müssen sie zur Strukturierung unseres regulären Ausdrucks verwenden. Dies sind ideale Optionen für die Verwendung einer Gruppe ohne Erfassung (?:). Eine nicht erfassende Gruppe macht genau das, wonach es sich anhört: Sie ermöglicht die Gruppierung und Verwendung von Zeichen in regulären Ausdrücken, erfasst sie jedoch nicht in einer nummerierten Gruppe:
Muster: (?:")([^"]+)(?:") 
string: Ich möchte nur „den Text in diesen Anführungszeichen“ .
Übereinstimmungen:             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
Gruppe:                 1111111111111111111111111111    
( Beispiel ) Der reguläre Ausdruck gleicht nun den zitierten Text sowie die Anführungszeichen selbst ab, aber die Erfassungsgruppe hat nur den zitierten Text erfasst. Warum sollten wir das tun? Der Punkt ist, dass Sie mit den meisten Engines für reguläre Ausdrücke Text aus Erfassungsgruppen wiederherstellen können, die in Ihren regulären Ausdrücken definiert sind. Wenn wir die nicht benötigten zusätzlichen Zeichen kürzen können, ohne sie in unsere Erfassungsgruppen aufzunehmen, wird es später einfacher, den Text zu analysieren und zu bearbeiten. So bereinigen Sie den CSV-Parser aus dem vorherigen Schritt:
Muster: (?:^|,)\s*(?:\"([^",]*)\"|([^", ]*)) 
string:   a , " b ", " cd ", e , f , " gh ", dfgi ,, k , "", l 
Übereinstimmungen: ^ ^ ^^^ ^ ^ ^^^ ^^^^ ^ ^ 
Gruppe:    2 1 111 2 2 111 2222 2 2    
( Beispiel ) Hier sind einige Dinge zu beachten:</mark> Erstens erfassen wir keine Kommas mehr, da wir die erfassende Gruppe (^|,)in eine nicht erfassende Gruppe geändert haben (?:^|,). Zweitens haben wir die Capture-Gruppe innerhalb der Nicht-Capture-Gruppe verschachtelt. Dies ist beispielsweise nützlich, wenn eine Gruppe von Zeichen in einer bestimmten Reihenfolge angezeigt werden soll, Ihnen aber nur eine Teilmenge dieser Zeichen wichtig ist. In unserem Fall brauchten wir Nicht- Anführungszeichen und Nicht- Kommas [^",]*, um in Anführungszeichen zu erscheinen, aber wir brauchten die Anführungszeichen selbst nicht wirklich, sodass sie nicht erfasst werden mussten. Abschließend <mark>beachten Sie</mark>, dass es im obigen Beispiel auch eine Nulllängenübereinstimmung zwischen den Zeichen kund gibt l. Die Anführungszeichen ""stellen die gesuchte Teilzeichenfolge dar, zwischen den Anführungszeichen stehen jedoch keine Zeichen, sodass die passende Teilzeichenfolge keine Zeichen enthält (Länge Null). <h3>Sollen wir unser Wissen festigen? Hier sind zweieinhalb Aufgaben, die uns dabei helfen werden:</h3> Schreiben Sie unter Verwendung nicht einfangender Gruppen (und einfangender Gruppen, Zeichenklassen usw.) einen regulären Ausdruck, der nur ordnungsgemäß formatierte Dateigrößen in der Zeile erfasst unten :
Muster:
Zeichenfolge:   6,6 KB 1..3 KB 12 KB 5G 3,3 MB KB .6,2 TB 9 MB .
Übereinstimmungen: ^^^^^ ^^^^^ ^^^^^^ ^^^^ 
Gruppe:    11111 1111 11111 111    
( Lösung ) Öffnende HTML-Tags beginnen mit <und enden mit >. HTML-Abschluss-Tags beginnen mit einer Zeichenfolge </und enden mit dem Zeichen >. Zwischen diesen Zeichen steht der Tag-Name. Können Sie einen regulären Ausdruck schreiben, um nur die Namen in den folgenden Tags zu erfassen? (Möglicherweise können Sie dieses Problem lösen, ohne nicht erfassende Gruppen zu verwenden. Versuchen Sie es auf zwei Arten zu lösen! Einmal mit Gruppen und einmal ohne.)
Muster:
Zeichenfolge:   <p> </span> <div> </kbd> <link> 
Treffer: ^^^ ^^^^^^ ^^^^^ ^^^^^^ ^^^^^^ 
Gruppe:    1 1111 111 111 1111    
( Lösung mit nicht erfassenden Gruppen ) ( Lösung ohne Verwendung nicht erfassender Gruppen ) <h2>Schritt 17: Backlinks \Nund benannte erfassende Gruppen</h2> RegEx: 20 kurze Schritte zur Beherrschung regulärer Ausdrücke.  Teil 4 - 3Obwohl ich Sie in der Einleitung gewarnt habe, dass beim Erstellen eines HTML-Parsers normalerweise reguläre Ausdrücke verwendet werden Da dies zu Kummer führt, ist dieses letzte Beispiel ein schöner Übergang zu einer weiteren (manchmal) nützlichen Funktion der meisten regulären Ausdrücke: Rückverweise. Backlinks sind wie sich wiederholende Gruppen, bei denen Sie versuchen können, denselben Text zweimal zu erfassen. Sie unterscheiden sich jedoch in einem wichtigen Aspekt: ​​Sie erfassen nur Zeichen für Zeichen denselben Text. Während eine sich wiederholende Gruppe es uns ermöglicht, so etwas einzufangen:
Muster: (he(?:[az])+) 
Zeichenfolge:   heyabcdefg hey heyo heyellow heyyyyyyyyy 
Übereinstimmungen: ^^^^^^^^^^ ^^^ ^^^^ ^^^^^^^^ ^^^ ^^^^^^^^ 
Gruppe:    1111111111 111 1111 11111111 11111111111    
( Beispiel ) ...dann stimmt der Backlink nur mit diesem überein:
Muster: (he([az])(\2+)) 
Zeichenfolge: heyabcdefg hey heyo heyellow heyyyyyyyyy 
Übereinstimmungen:                              ^^^^^^^^^^^ 
Gruppe:                                 11233333333    
( Beispiel ) Wiederholte Erfassungsgruppen sind nützlich, wenn Sie dasselbe Muster wiederholt abgleichen möchten, während Backlinks gut sind, wenn Sie denselben Text abgleichen möchten. Beispielsweise könnten wir mithilfe eines Backlinks versuchen, passende öffnende und schließende HTML-Tags zu finden:
Muster: <(\w+)[^>]*>[^<]+<\/\1> 
Zeichenfolge:   <span style="color: red">hey</span> 
Treffer: ^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
Gruppe:    1111    
( Beispiel ) <mark>Bitte beachten Sie</mark>, dass dies ein extrem vereinfachtes Beispiel ist und ich dringend davon abraten würde, einen auf regulären Ausdrücken basierenden HTML-Parser zu schreiben. Das ist eine sehr komplexe Syntax und wird Sie höchstwahrscheinlich krank machen. Benannte Capture-Gruppen sind Backlinks sehr ähnlich, daher werde ich sie hier kurz behandeln. Der einzige Unterschied zwischen Rückverweisen und einer benannten Capture-Gruppe besteht darin, dass ... eine benannte Capture-Gruppe einen Namen hat:
Muster: <(?<tag>\w+)[^>]*>[^<]+<\/(?P=tag)></tag> 
Zeichenfolge:   <span style="color: red">hey< /span> 
Treffer: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
Gruppe:    1111    
( Beispiel ) Sie können eine benannte Erfassungsgruppe mit der Syntax (?<name>...) oder (?'name'...) (.NET-kompatibler regulärer Ausdruck) oder mit dieser Syntax (?P<name>) erstellen. ..) oder (?P'name'...) (Python-kompatibler regulärer Ausdruck). Da wir PCRE (Perl Compatible Regular Expression) verwenden, das beide Versionen unterstützt, können wir hier eine von beiden verwenden. (Java 7 hat die .NET-Syntax kopiert, jedoch nur die Version mit spitzen Klammern. Anmerkung des Übersetzers) Um eine benannte einfangende Gruppe später in einem regulären Ausdruck zu wiederholen, verwenden wir \<kname> oder \k'name' (.NET) oder (? P=Name) (Python). Auch hier unterstützt PCRE alle diese verschiedenen Optionen. Mehr über benannte Capture-Gruppen können Sie hier lesen , aber das war das meiste, was Sie wirklich über sie wissen müssen. <h3>Aufgabe, uns zu helfen:</h3> Verwenden Sie Backlinks, damit ich mich an ... ähm ... den Namen dieser Person erinnern kann.
Muster:
string: „Hallo, mein Name ist Joe.“ [später] „Wie heißt dieser Typ? Joe ?“
Übereinstimmungen:        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^ 
Gruppe:                  111    
( Lösung ) <h2>Schritt 18: Lookahead und Lookbehind</h2> RegEx: 20 kurze Schritte zur Beherrschung regulärer Ausdrücke.  Teil 4 - 4Jetzt werden wir uns mit einigen der erweiterten Funktionen regulärer Ausdrücke befassen. Ich benutze alles bis Schritt 16 ziemlich oft. Diese letzten Schritte sind jedoch nur für Leute gedacht, die Regex sehr ernsthaft verwenden, um sehr komplexe Ausdrücke abzugleichen. Mit anderen Worten: Meister der regulären Ausdrücke. „Looking Forward“ und „Looking Back“ mögen ziemlich kompliziert erscheinen, aber sie sind wirklich nicht zu kompliziert. Sie ermöglichen es Ihnen, etwas Ähnliches zu tun, wie wir es zuvor mit nicht erfassenden Gruppen gemacht haben: Überprüfen Sie, ob Text unmittelbar vor oder unmittelbar nach dem eigentlichen Text vorhanden ist, den wir abgleichen möchten. Angenommen, wir möchten nur die Namen von Dingen abgleichen, die den Leuten gefallen, aber nur, wenn sie davon begeistert sind (nur wenn sie ihren Satz mit einem Ausrufezeichen beenden). Wir könnten so etwas tun:
Muster: (\w+)(?=!) 
string: Ich mag Schreibtisch. Ich schätze Hefter. Ich liebe Lampe !
Übereinstimmungen:                                           ^^^^ 
Gruppe:                                              1111    
( Beispiel ) Sie können sehen, dass die obige Erfassungsgruppe (\w+), die normalerweise mit jedem der Wörter in der Passage übereinstimmt, nur mit dem Wort lamp übereinstimmt. Positiver Look-Ahead (?=!)bedeutet, dass wir nur Sequenzen finden können, die mit enden, !das Ausrufezeichen selbst jedoch nicht. Dies ist ein wichtiger Unterschied, da wir bei nicht erfassenden Gruppen zwar den Charakter abgleichen, ihn aber nicht erfassen. Bei Lookaheads und Lookbehinds verwenden wir ein Zeichen, um unseren regulären Ausdruck zu erstellen, vergleichen ihn dann aber nicht einmal mit sich selbst. Wir können es später in unserem regulären Ausdruck abgleichen. Es gibt vier Arten von Lookaheads und Lookbehinds: positiver Lookahead (?=...), negativer Lookahead (?!...), positiver Lookahead (?<=...) und negativer Lookahead (?<!. ..) . Sie machen das, wonach sie klingen: Positives Lookahead und Lookbehind ermöglichen es der Engine für reguläre Ausdrücke, den Abgleich nur dann fortzusetzen, wenn der im Lookahead/Lookbehind enthaltene Text tatsächlich übereinstimmt. Negativer Lookahead und Lookbehind bewirken das Gegenteil – sie ermöglichen eine Übereinstimmung des regulären Ausdrucks nur, wenn der im Lookahead/Lookbehind enthaltene Text nicht übereinstimmt. Beispielsweise möchten wir Methodennamen nur in einer Kette von Methodensequenzen abgleichen, nicht das Objekt, auf das sie angewendet werden. In diesem Fall muss jedem Methodennamen ein vorangestellt werden .. Ein regulärer Ausdruck mit einem einfachen Lookback kann hier hilfreich sein:
Muster: (?<=\.)(\w+) 
Zeichenfolge: myArray. flatMap.aggregate.summarise.print !
Übereinstimmungen:         ^^^^^^^ ^^^^^^^^^ ^^^^^^^^^ ^^^^^ 
Gruppe:            1111111 111111111 111111111 11111    
( Beispiel ) Im obigen Text stimmen wir mit jeder Folge von Wortzeichen überein \w+, jedoch nur, wenn ihnen das Zeichen vorangestellt ist .. Mit nicht erfassenden Gruppen könnten wir etwas Ähnliches erreichen, aber das Ergebnis ist etwas chaotischer:
Muster: (?:\.)(\w+) 
string: myArray .flatMap.aggregate.summarise.print !
Übereinstimmungen:        ^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^ ^^^^^ 
Gruppe:            1111111 111111111 111111111 11111    
( Beispiel ) Obwohl es kürzer ist, entspricht es Zeichen, die wir nicht benötigen. Obwohl dieses Beispiel trivial erscheinen mag, können Lookaheads und Lookbehinds uns wirklich dabei helfen, unsere regulären Ausdrücke zu bereinigen. <h3>Bis zum Ziel sind nur noch sehr wenige übrig! Die folgenden zwei Aufgaben bringen uns diesem Ziel einen Schritt näher:</h3> Negatives Lookbehind (?<!...) ermöglicht es der Engine für reguläre Ausdrücke, nur dann weiterhin nach einer Übereinstimmung zu suchen, wenn der im negativen Lookbehind enthaltene Text dies nicht tut bis zum Rest des Textes angezeigt, mit dem Sie eine Übereinstimmung finden müssen. Beispielsweise könnten wir einen regulären Ausdruck verwenden, um nur die Nachnamen von Frauen abzugleichen, die an einer Konferenz teilnehmen. Dazu möchten wir sicherstellen, dass dem Nachnamen der Person kein vorangestelltes Mr.. Können Sie dafür einen regulären Ausdruck schreiben? (Bei Nachnamen kann davon ausgegangen werden, dass sie mindestens vier Zeichen lang sind.)
Muster:
Zeichenfolge: Mr. Braun, Frau Smith , Frau Jones , Miss Daisy , Mr. Grün
Übereinstimmungen:                ^^^^^ ^^^^^ ^^^^^ 
Gruppe:                   11111 11111 11111    
( Lösung ) Nehmen wir an, wir löschen eine Datenbank und haben eine Informationsspalte, die Prozentsätze darstellt. Leider haben einige Leute Zahlen als Dezimalwerte im Bereich [0,0, 1,0] geschrieben, während andere Prozentsätze im Bereich [0,0 %, 100,0 %] geschrieben haben und wieder andere Prozentwerte geschrieben haben, aber das wörtliche Prozentzeichen vergessen haben %. Können Sie mit negativem Lookahead (?!...) nur die Werte markieren, die Prozentsätze sein sollten, denen aber Ziffern fehlen %? Dies müssen Werte sein, die unbedingt größer als 1,00 sind, jedoch ohne nachgestellte %. (Keine Zahl darf mehr als zwei Ziffern vor oder nach dem Dezimalpunkt enthalten.) <mark>Beachten Sie</mark>, dass diese Lösung äußerst schwierig ist . Wenn Sie dieses Problem lösen können, ohne sich meine Antwort anzusehen, dann verfügen Sie bereits über enorme Kenntnisse in regulären Ausdrücken!
Muster:
Zeichenfolge: 0,32 100,00 5,6 0,27 98 % 12,2 % 1,01 0,99 % 0,99 13,13 1,10 
Übereinstimmungen:      ^^^^^^ ^^^ ^^^^ ^^^^^ ^^^^ 
Gruppe:         111111 111 1111 11111 1111    
( Lösung ) <h2>Schritt 19: Bedingungen in regulären Ausdrücken</h2> RegEx: 20 kurze Schritte zur Beherrschung regulärer Ausdrücke.  Teil 4 - 5Wir haben jetzt den Punkt erreicht, an dem die meisten Leute keine regulären Ausdrücke mehr verwenden. Wir haben wahrscheinlich 95 % der Anwendungsfälle für einfache reguläre Ausdrücke abgedeckt, und alles, was in den Schritten 19 und 20 erledigt wird, wird normalerweise von einer umfassenderen Textbearbeitungssprache wie awk oder sed (oder einer Allzweck-Programmiersprache) erledigt. Lassen Sie uns jedoch fortfahren, damit Sie wissen, was ein regulärer Ausdruck wirklich bewirken kann. Obwohl reguläre Ausdrücke nicht Turing-vollständig sind , bieten einige Engines für reguläre Ausdrücke Funktionen, die einer vollständigen Programmiersprache sehr ähnlich sind. Ein solches Merkmal ist „Zustand“. Regex-Bedingungen ermöglichen Wenn-Dann-Sonst-Anweisungen, bei denen der ausgewählte Zweig entweder durch den „Vorwärtsblick“ oder den „Rückblick“ bestimmt wird, den wir im vorherigen Schritt kennengelernt haben. Beispielsweise möchten Sie möglicherweise nur gültige Einträge in einer Datumsliste abgleichen:
Muster: (?<=Feb )([1-2][0-9])|(?<=Mar )([1-2][0-9]|3[0-1]) 
Zeichenfolge: Arbeitsdaten : 28. Februar , 29. Februar, 30. Februar, 30. März , 31. März  
Spiele:                   ^^ ^^ ^^ ^^ 
Gruppe:                      11 11 22 22    
( Beispiel ) <mark>Beachten Sie</mark>, dass die oben genannten Gruppen auch nach Monat indiziert sind. Wir könnten einen regulären Ausdruck für alle 12 Monate schreiben und nur gültige Daten erfassen, die dann in nach Monaten des Jahres indizierten Gruppen zusammengefasst würden. Das Obige verwendet eine Art if-ähnliche Struktur, die nur dann nach Übereinstimmungen in der ersten Gruppe sucht, wenn „Feb“ vor einer Zahl steht (und das Gleiche gilt auch für die zweite). Aber was wäre, wenn wir nur für Februar eine Sonderverarbeitung nutzen wollten? Etwas wie „Wenn der Zahl „Feb“ vorangestellt ist, tun Sie dies, andernfalls machen Sie das andere.“ So funktionieren Bedingungen:
Muster: (?(?<=Feb )([1-2][0-9])|([1-2][0-9]|3[0-1])) 
Zeichenfolge: Bearbeitungsdaten: 28. Februar , 29. Februar , 30. Februar, 30. März , 31. März  
Spiele:                   ^^ ^^ ^^ ^^ 
Gruppe:                      11 11 22 22    
( Beispiel ) Die if-then-else-Struktur sieht wie folgt aus: (?(If)then|else), wobei (if) durch „Look Forward“ oder „Look Back“ ersetzt wird. Im obigen Beispiel wird (if) als geschrieben (?<=Feb). Sie können sehen, dass wir Daten gefunden haben, die größer als 29 sind, allerdings nur, wenn diese nicht auf „Feb“ folgten. Die Verwendung von Lookbehinds in bedingten Ausdrücken ist nützlich, wenn Sie sicherstellen möchten, dass vor der Übereinstimmung Text steht. Positive Lookahead-Bedingungen können verwirrend sein, da die Bedingung selbst mit keinem Text übereinstimmt. Wenn Sie also möchten, dass die if-Bedingung jemals einen Wert hat, muss sie wie folgt mit einem Lookahead vergleichbar sein:
Muster: (?(?=exact)exact|else)wo 
String: Exact else Exactwo elsewo  
stimmt überein:            ^^^^^^^ ^^^^^^
( Beispiel ) Dies bedeutet, dass positive Lookahead-Bedingungen nutzlos sind. Sie überprüfen, ob sich der Text im Vordergrund befindet, und geben dann ein passendes Muster an, dem Sie dann folgen können. Der bedingte Ausdruck hilft uns hier überhaupt nicht weiter. Sie können das Obige auch einfach durch einen einfacheren regulären Ausdruck ersetzen:
Muster: (?:exact|else)wo 
String: Exact else Exactwo elsewo  
stimmt überein:            ^^^^^^^ ^^^^^^
( Beispiel ) Die Faustregel für bedingte Ausdrücke lautet also: testen, testen und noch einmal testen. Andernfalls werden Lösungen, die Sie für offensichtlich halten, auf aufregendste und unerwartete Weise scheitern :) <h3>Hier kommen wir zum letzten Aufgabenblock, der uns vom letzten, 20. Schritt trennt:</h3> Schreiben Sie einen regulären Ausdruck, der verwendet einen negativen bedingten Lookahead-Ausdruck, um zu testen, ob das nächste Wort mit einem Großbuchstaben beginnt. Wenn ja, nehmen Sie nur einen Großbuchstaben und dann die Kleinbuchstaben. Wenn dies nicht der Fall ist, greifen Sie zu den Wortzeichen.
Muster:
Zeichenfolge:   Jones Smith 9sfjn Hobbes 23r4tgr9h CSV Csv vVv 
Übereinstimmungen: ^^^^^ ^^^^^ ^^^^^ ^^^^^^ ^^^^^^^^^ ^^^ ^^^ 
Gruppe:    22222 22222 11111 222222 111111111 222 111    
( Lösung ) Schreiben Sie einen negativen Lookbehind-Bedingungsausdruck, der Text ownsnur erfasst, wenn ihm kein Text vorangestellt ist cl, und der Text nur erfasst, oudswenn ihm Text vorangestellt ist cl. (Ein etwas konstruiertes Beispiel, aber was kann man tun ...)
Muster:
string: Diese Clowns besitzen einige Wolken . Ouds.
Übereinstimmungen:              ^^^^ ^^^^   
( Lösung ) <h2>Schritt 20: Rekursion und weitere Untersuchung</h2> RegEx: 20 kurze Schritte zur Beherrschung regulärer Ausdrücke.  Teil 4 - 6Tatsächlich lässt sich in einer 20-stufigen Einführung in jedes Thema eine Menge zusammenfassen, und reguläre Ausdrücke bilden da keine Ausnahme. Es gibt viele verschiedene Implementierungen und Standards für reguläre Ausdrücke , die im Internet zu finden sind. Wenn Sie mehr erfahren möchten, empfehle ich Ihnen, einen Blick auf die wunderbare Website „regularexpressions.info“ zu werfen . Sie ist eine fantastische Referenz und ich habe dort auf jeden Fall viel über reguläre Ausdrücke gelernt. Ich kann es wärmstens empfehlen, ebenso wie regex101.com zum Testen und Veröffentlichen Ihrer Kreationen. In diesem letzten Schritt werde ich Ihnen etwas mehr Wissen über reguläre Ausdrücke vermitteln, insbesondere wie man rekursive Ausdrücke schreibt. Einfache Rekursionen sind ziemlich einfach, aber lassen Sie uns darüber nachdenken, was das im Kontext eines regulären Ausdrucks bedeutet. Die Syntax für eine einfache Rekursion in einem regulären Ausdruck lautet wie folgt: (?R)?. Aber natürlich muss diese Syntax im Ausdruck selbst vorkommen. Was wir tun werden, ist, den Ausdruck beliebig oft in sich selbst zu verschachteln. Zum Beispiel:
Muster: (hey(?R)?oh) 
Zeichenfolge:   heyoh heyyoh heyheyohoh hey oh heyhey hey heyheyohoh  
Übereinstimmungen: ^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ 
Gruppe:    11111 1111111111 1111111111    
( Beispiel ) Da der verschachtelte Ausdruck optional ist ( (?R)folgt ?), besteht die einfachste Übereinstimmung darin, die Rekursion einfach vollständig zu ignorieren. Also, hey, und dann ohentspricht ( heyoh). Um einen komplexeren Ausdruck als diesen zu finden, müssen wir den passenden Teilstring finden, der an der Stelle im Ausdruck, an der wir (?R)die Sequenz eingefügt haben, in sich selbst verschachtelt ist. Mit anderen Worten, wir könnten „heyheyohoh“ oder „heyheyheyohohoh“ usw. finden. Das Tolle an diesen verschachtelten Ausdrücken ist, dass sie Sie im Gegensatz zu Rückverweisen und benannten Erfassungsgruppen nicht auf den genauen Text beschränken, den Sie zuvor Zeichen für Zeichen abgeglichen haben. Zum Beispiel:
Muster: ([Hh][Ee][Yy](?R)?oh) 
Zeichenfolge:   heyoh heyyoh hEyHeYohoh hey oh heyhey hEyHeYHEyohohoh  
Übereinstimmungen: ^^^^^ ^^^^^^^^^^ ^^^^^ ^^^^^^^^^^ 
Gruppe:    11111 1111111111 111111111111111    
( Beispiel ) Sie können sich vorstellen, dass die Engine für reguläre Ausdrücke Ihren regulären Ausdruck buchstäblich beliebig oft kopiert und in sich selbst einfügt. Das bedeutet natürlich, dass es manchmal nicht das tut, was Sie vielleicht erhofft haben:
Muster: ((?:\(\*)[^*)]*(?R)?(?:\*\))) 
Zeichenfolge: (* Kommentar (* verschachtelt *) nicht *)
Übereinstimmungen:            ^^^^^^^^^^^^ 
Gruppe:               111111111111    
( Beispiel ) Können Sie erklären, warum dieser reguläre Ausdruck nur den verschachtelten Kommentar und nicht den äußeren Kommentar erfasst? Eines ist sicher: Wenn Sie komplexe reguläre Ausdrücke schreiben, testen Sie sie immer, um sicherzustellen, dass sie so funktionieren, wie Sie es sich vorstellen. Diese Hochgeschwindigkeitsrallye auf den Straßen der regulären Ausdrücke ist zu Ende. Ich hoffe, Ihnen hat diese Reise gefallen. Nun, und zum Schluss werde ich hier, wie ich zu Beginn versprochen habe, einige nützliche Links für ein tiefergehendes Studium des Materials hinterlassen:
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION