English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Regulärer Ausdrucks语法零宽断言:
Die Null-Breite-Vorabfrage ist ein schwieriges Thema in der regulären Ausdrucks语法, daher wird dieser Abschnitt hauptsächlich aus der Perspektive der Match-Prinzipien analysiert. Die Null-Breite-Vorabfrage hat auch andere Namen, wie "Rückansicht" oder "Vorsuche" usw., aber dies sind nicht unsere Hauptanliegen.
1. Grundbegriff:
Die Null-Breite-Vorabfrage, wie der Name schon sagt, ist eine Null-Breite-Matchung, die matchenden Inhalte werden nicht in das Match-Ergebnis aufgenommen, das endgültige Match-Ergebnis ist nur eine Position.
Die Funktion ist, eine限定条件 hinzuzufügen, um zu bestimmen, dass die Zeichen vor oder nach dieser Position die限定条件 erfüllen müssen, damit der Wortausdruck in der regulären Ausdrucks语法 erfolgreich matchen kann.
Hinweis: Hierbei genannte Unterexpressionen sind nicht nur Ausdrücke, die in kleinen Klammern eingeschlossen sind, sondern jede beliebige Match-Unit in der regulären Ausdrucks语法.
javascript unterstützt nur die Null-Breite-Vorabfrage, und die Null-Breite-Vorabfrage kann in die positive Null-Breite-Vorabfrage und die negative Null-Breite-Vorabfrage unterteilt werden.
Hier ist ein Beispielcode:
Beispielcode eins:
var str="abZW863"; var reg=/ab(?=[A-Z])/; console.log(str.match(reg));
In diesem Code, die Bedeutung der regulären Ausdrucks语法 ist: die Zeichenkette "ab", die gefolgt wird von einer beliebigen Großbuchstabe, zu matchen. Das endgültige Match-Ergebnis ist "ab", weil der Null-Breite-Anker "(?=[A-Z])" matcht keine Zeichen, sondern wird nur verwendet, um zu bestimmen, dass die Position nach diesem Zeichen eine Großbuchstabe sein muss.
Beispielcode zwei:
var str="abZW863"; var reg=/ab(?![A-Z])/; console.log(str.match(reg));
In diesem Code, die Bedeutung der regulären Ausdrucks语法是: die Zeichenkette "ab" zu matchen, die nicht gefolgt wird von einer Großbuchstabe. Die reguläre Ausdrucks语法 konnte keine Zeichen matchen, weil die "ab" in der Zeichenkette gefolgt wird von einer Großbuchstabe.
Zwei. Matching-Prinzip:
Der obige Code stellt nur auf konzeptioneller Ebene dar, wie leere Assertion matchen.
Nächste wird das Matching-Prinzip vorgestellt, um zu erläutern, wie positive und negative leere Assertion matchen.
1.Positive leere assertion:
Hier ist ein Beispielcode:
var str="<div>antzone"; var reg=/^(?=<)<[^>]+>\w+/; console.log(str.match(reg));
Der Matching-Prozess ist wie folgt:
Zunächst wird die Kontrolle durch "^" des regulären Ausdrucks erhalten, beginnt mit der Position 0 zu matchen, matcht den Anfang der Position 0, Match-Erfolg, dann wird die Kontrolle an "(?=<)" ist ebenfalls leer, da "^" leer ist, daher "(?=<)" beginnt ebenfalls mit der Position 0 zu matchen, es ist bestimmt, dass es auf der rechten Seite der Position das Zeichen "<" sein muss, und das Zeichen auf Position 0 ist genau "<", Match-Erfolg, dann wird die Kontrolle an "<" übergeben, da "(?=<)" ist ebenfalls leer, daher beginnt es mit der Position 0 zu matchen, daher ist das Match-Ergebnis erfolgreich, die nachfolgenden Matching-Prozesse werden nicht näher erläutert.
2.Negative leere assertion:
Hier ist ein Beispielcode:
var str="abZW863ab88"; var reg=/ab(?![A-Z])/g; console.log(str.match(reg));
Der Matching-Prozess ist wie folgt:
Zunächst wird die Kontrolle durch das Zeichen "a" des regulären Ausdrucks "a" erhalten, beginnt mit der Position 0 zu matchen, Match-Erfolg des Zeichens "a", dann die Kontrolle wird an "b" übergeben und von der Position1Beginnt mit der Versuchsmatch, Match-Erfolg, dann die Kontrolle an "(?![A-Z])", es beginnt ab der Position2Beginnt mit der Versuchsmatch, es ist bestimmt, dass es auf der rechten Seite der Position keine beliebige Großbuchstabe geben darf, während die rechte Position der Großbuchstabe "Z" ist, Match-Erfolg, dann die Kontrolle wird wieder an das Zeichen "a" übergeben und von der Position1Beginnt mit der Versuchsmatch, Match-Erfolg, dann die Kontrolle an "b" übergeben, dann von der Position2Beginnt mit der Versuchsmatch, Match-Erfolg, dann die Kontrolle an "b" übergeben, dann von der Position7Beginnt mit der Versuchsmatch erfolgreich, dann die Kontrolle an "b" übergeben, dann von der Position8Beginnt mit der Versuchsmatch, Match-Erfolg, dann die Kontrolle an "(?![A-Z])", es beginnt ab der Position9Beginnt mit der Versuchsmatch, es ist bestimmt, dass es auf der rechten Seite der Position keine Großbuchstaben geben darf, Match-Erfolg, aber es wird nicht wirklich ein Zeichen matchen, daher ist das endgültige Match-Ergebnis "ab".
Hier sind einige Ergänzungen
Ein Leerer assertion ist eine Methode in regulären Ausdrücken, reguläre Ausdrücke in der Informatik sind eine Art von Einzeldatei, die dazu dient, eine Reihe von Zeichenketten zu beschreiben oder abzustimmen, die einer bestimmten Syntax entsprechen.
Definition und Erklärung
Ein Leerer assertion ist eine Methode in regulären Ausdrücken
Reguläre Ausdrücke in der Informatik sind eine Art von Einzeldatei, die dazu dient, eine Reihe von Zeichenketten zu beschreiben oder abzustimmen, die einer bestimmten Syntax entsprechen. Sie werden in vielen Texteditoren oder anderen Werkzeugen häufig verwendet, um Suchanfragen durchzuführen und/oder Textinhalte, die einem bestimmten Muster entsprechen, zu ersetzen. Viele Programmiersprachen unterstützen die Verwendung von regulären Ausdrücken für Stringoperationen. Zum Beispiel ist in Perl ein leistungsstarkes reguläres Ausdrucksmodul integriert. Der Begriff "regulärer Ausdruck" wird normalerweise als "regex" abgekürzt, das Singular ist regexp, regex, das Plural ist regexps, regexes, regexen.
Zero-Width Assertions
wird verwendet, um nach etwas zu suchen, das vor oder nach bestimmten Inhalten steht (aber nicht einschließlich dieser Inhalte), das bedeutet, sie funktionieren wie \b, ^, $, um einen Ort zu spezifizieren, der bestimmte Bedingungen (d.h. Ansprüche) erfüllen muss, daher werden sie auch Zero-Width Assertions genannt. Es ist am besten, mit Beispielen zu erklären: Assertions werden verwendet, um eine Tatsache zu bestätigen, die wahr sein sollte. In regulären Ausdrücken wird nur fortgegangen, wenn der Anspruch wahr ist.
(?=exp) wird auch Zero-Width Positive Lookahead Assertion genannt, es wird behauptet, dass nach der Position, an der es sich befindet, der Ausdruck "exp" gematcht werden kann. Zum Beispiel \b(?=re)\w+b, wird das Nachteil eines Wortes auswählen, das mit "re" beginnt (außer "re" selbst), zum Beispiel, wenn man "reading a book." sucht, wird "ading" gematcht.
var reg = new Regex(@"\w+(?=ing)"); var str = "muing"; Console.WriteLine(reg.Match(str).Value);//zurückgegeben mu
(?<=exp) wird auch Zero-Width Positive Lookbehind Assertion genannt, es wird behauptet, dass vor der Position, an der es sich befindet, der Ausdruck "exp" gematcht werden kann. Zum Beispiel \b\w+(?<=ing\b) wird den ersten Teil der Wörter auswählen, die auf "ing" enden (außer "ing" selbst), zum Beispiel, wenn man "I am reading." sucht, wird "read" gematcht.
Wenn du eine lange Zahl hast und dir vorstellst, dass du eine Komma alle drei Stellen hinzufügen möchtest (natürlich beginnend von rechts), kannst du so suchen, dass du die Stellen vorne und drin hinzufügen musst: ((?=\d)\d{3})+\b, um1234567890 wird gesucht, das Ergebnis ist234567890.
Dieser Beispiel verwendet beide Arten von Vorwärtsprediktionsanzeigern: (?<=\s)\d+(?=\s) stimmt mit Ziffern überein, die durch Leerzeichen getrennt sind (wiederholt betont, dass dies nicht um diese Leerzeichen geht).
Negative Breitenansprüche
Wir haben bereits erwähnt, wie man sucht, dass ein Zeichen nicht vorhanden ist oder nicht zu einer bestimmten Zeichengruppe gehört (Negation). Aber was passiert, wenn man sicherstellen möchte, dass ein Zeichen nicht vorhanden ist, aber nicht möchte, dass es gematcht wird? Zum Beispiel, wenn man solche Wörter sucht--es enthält das Alphabet q, aber das q wird nicht von einem Alphabetu gefolgt, wir können versuchen, so zu tun:
b\w*q[^u]\w*b wird das Wort auswählen, das ein q enthält, das nicht von einem u gefolgt wird. Aber wenn man mehr tests durchführt (oder wenn man足够敏锐, kann man es sofort beobachten), dann stellt man fest, dass, wenn q am Ende eines Wortes steht, wie z.B. Iraq, Benq, dieser Ausdruck fehlschlägt. Dies liegt daran, dass [^u] immer ein Zeichen auswählen muss, also wird [^u] wenn q der letzte Zeichen eines Wortes ist, den nachfolgenden Worttrennzeichen (das möglicherweise ein Leerzeichen, ein Punkt oder etwas anderes ist) auswählen, das nach \w*b wird den nächsten Wortbestandteil auswählen, also b\w*q[^u]\w*b kann das gesamte Iraq fighting auswählen. Negative Breitenansprüche können dieses Problem lösen, da sie nur eine Position auswählen und keine Zeichen verbrauchen. Jetzt können wir das Problem so lösen: b\w*q(?!u)\w*\b).
Nullbreite negative VorhersageAssertion (?!exp), Assertion, dass sich die Position nicht mit dem Ausdruck 'exp' entsprechen kann. Zum Beispiel: \d{3})(?!\d) entspricht einer dreistelligen Zahl, und nach dieser Zahl dürfen keine Ziffern folgen;\b((?!abc)\w)+\b entspricht einem Wort, das keine kontinuierliche Zeichenkette 'abc' enthält.
Gleiches gilt für (?<!exp), Nullbreite negative RückblickAssertion, um zu behaupten, dass sich die Position vor der eigenen Position nicht mit dem Ausdruck 'exp' entsprechen kann: (?<![a-z])\d{7} entspricht einem Siebenstelligem Nummer, das nicht mit einem kleinen Buchstaben beginnt.
Ein komplexeres Beispiel: (?<=<(\w+)>).*(?=<\/\1>) entspricht dem Inhalt innerhalb einfacher HTML-Tags ohne Attribute. (<?=(\w+)>) spezifiziert einen solchen Präfix: ein Wort, das in eckigen Klammern eingeschlossen ist (z.B. möglicherweise <b>), gefolgt von .*(beliebige Zeichenkette), gefolgt von einem Suffix (?=<\/\1>). Beachten Sie das \/verwendet das vorangegangene Zeichenset;\1dann ist es eine umgekehrte Referenz, die genau das erste erfasste Gruppensuffix referenziert, das vorangegangene (\w+) entspricht dem Inhalt, so dass, wenn das Präfix tatsächlich <b> ist, das Suffix < ist/b> endet. Der gesamte Ausdruck entspricht <b> und </b> zwischen dem Inhalt (erneut darauf hingewiesen, dass der Präfix und das Suffix selbst nicht eingeschlossen sind).
Das war etwas kompliziert. Lassen Sie uns etwas hinzufügen:
Assertions werden verwendet, um eine Tatsache zu behaupten, die wahr sein sollte. In regulären Ausdrücken wird nur fortgegangen, wenn die Assertion wahr ist.
Die nächsten vier werden verwendet, um Dinge zu finden, die vor oder nach bestimmten Inhalten stehen (aber nicht einschließlich dieser Inhalte), d.h. sie dienen wie \b, ^, $ dazu, einen Ort zu spezifizieren, der bestimmte Bedingungen (d.h. Assertions) erfüllen muss, daher werden sie auch Nullbreite Assertions genannt. Es ist am besten, mit Beispielen zu erklären:
(?=exp) wird auch als Nullbreite positive VorhersageAssertion bezeichnet, es behauptet, dass sich die Position nach der eigenen Position mit dem Ausdruck 'exp' entsprechen kann. Zum Beispiel \b\w+(?=ing\b),passt auf den ersten Teil der Wörter, die mit 'ing' enden (außer 'ing' selbst), z.B. wenn man 'I'm singing while you're dancing' sucht, passt es auf 'sing' und 'danc'.
(?<=exp) wird auch als Nullbreite positive RückblickAssertion bezeichnet, es behauptet, dass sich die Position vor der eigenen Position mit dem Ausdruck 'exp' entsprechen kann. Zum Beispiel (?<=\bre)\w+Es passt auf den zweiten Teil der Wörter, die mit 're' beginnen (außer 're' selbst), z.B. wenn man 'reading a book' sucht, passt es auf 'ading'.
Wenn du eine lange Zahl hast und dir vorstellst, dass du eine Komma alle drei Stellen hinzufügen möchtest (natürlich beginnend von rechts), kannst du so suchen, dass du die Stellen vorne und drin hinzufügen musst: ((?<=\d)\d{3})*\b, um1234567890 wird gesucht, das Ergebnis ist234567890.
Dieser Beispiel verwendet beide Arten von Vorwärtsprediktionsanzeigern: (?<=\s)\d+(?=\s) stimmt mit Ziffern überein, die durch Leerzeichen getrennt sind (wiederholt betont, dass dies nicht um diese Leerzeichen geht).
Zusätzlicher Hinweis:
Kürzlich, um HTML-Dateien zu bearbeiten, musste ich nach bestimmten Stellen suchen und ersetzen. Aus diesem Anlass habe ich das System der Regulären Ausdrücke systematisch gelernt, obwohl ich sie vorher auch schon verwendet habe, aber jedes Mal nur kurz gelernt und durchgekommen. Während des Lernens bin ich auf viele Probleme gestoßen, insbesondere auf die Nullbreiten-Vorwärtsprediktionsanzeiger (ich muss nochmal aus der Puste kommen, überall im Internet ist das gleiche Kopieren und Einfügen von Inhalten zu finden, ich habe viele gleiche Dinge überprüft, das war wirklich schweißtreibend!!!), daher habe ich hier meine eigenen Verständnisse niedergeschrieben, um sie in der Zukunft leicht zu konsultieren!
Was ist ein Nullbreiten-Vorwärtsprediktionsanzeiger? Schauen wir uns die offizielle Definition auf MSDN an
(?= Unterexpression)
Ein Beispiel für einen Nullbreiten-Vorwärtsprediktionsanzeiger. Es wird fortgesetzt, wenn das Unterexpressions auf der rechten Seite dieser Position übereinstimmt. Zum Beispiel, \w+(?=\d) stimmt mit Wörtern, die eine Zahl folgen, überein, nicht jedoch mit der Zahl selbst.
Ein klassischer Fall: Ein Wort endet auf ing, und wir müssen das Vorherige von ing erhalten
var reg = new Regex(@"\w+(?=ing)"); var str = "muing"; Console.WriteLine(reg.Match(str).Value);//zurückgegeben mu
Das sind Beispiele, die überall im Internet zu finden sind. Bis hierher vielleicht verstanden, dass es sich um das Vorherige des exp-Ausdrucks handelt, der zurückgegeben wird.
Schauen wir uns den folgenden Code an
var reg = new Regex(@"a(?=b)c"); var str = "abc"; Console.WriteLine(reg.IsMatch(str));//false zurückgegeben
Warum wird false zurückgegeben?
Tatsächlich hat die offizielle Definition von MSDN dies bereits gesagt, sie hat es nur sehr offiziell ausgedrückt. Hier müssen wir auf einen wichtigen Punkt achten: diese Position. Richtig, es geht um die Position und nicht um das Zeichen. Also, in Verbindung mit der offiziellen Definition und dem ersten Beispiel, um den zweiten Beispiel zu verstehen:
Da a后面是b,因此此时返回了匹配内容a(从第一个例子可以知道,只返回a,不返回exp匹配的内容),此时a(?=b)c63Der Teil =b) wurde bereits gelöst, nun müssen wir das Problem der Übereinstimmung von c lösen. Wenn wir die Übereinstimmung von c überprüfen, wo sollten wir in der Zeichenkette abc anfangen? In Verbindung mit der offiziellen Definition wissen wir, dass wir von der Position des Unterexpressions nach rechts beginnen müssen. Das bedeutet, dass wir von der Position von b beginnen, aber b stimmt nicht mit a( überein.63;=b)c der verbleibende Teil c, also ist abc nicht übereinstimmend mit a(?=b)c wurde
Dann wie soll das Muster oben übereinstimmen, wie soll die reguläre Ausdrucksform geschrieben werden?
Die Antwort ist: a(?=b)bc
Natürlich, jemand könnte sagen, dass es direkt abc übereinstimmt und man so herumprobieren muss? Natürlich nicht, nur um zu erklären, wie Zero-Width Positive Lookahead Assertion tatsächlich ist? Andere Zero-Width Assertions sind auch dasselbe Prinzip!
Zusatz III
(?=exp): Zero-Width Positive Lookahead Assertion, es bestätigt, dass die Position nach der eigenen Erscheinung mit dem Ausdruck exp übereinstimmt。
#match nach _path, Ergebnis product
'product_path'.scan /(product)(?=_path)/
(?<=exp): Zero-Width Positive Lookbehind Assertion, es bestätigt, dass die Position vor der eigenen Erscheinung mit dem Ausdruck exp übereinstimmt
#match vor name:, Ergebnis wangfei
'name:wangfei'.scan /(?<=name:)(wangfei)/ #wangfei
(?!exp): Zero-Width Negative Lookahead Assertion, um zu bestätigen, dass die Position nach diesem Ort nicht mit dem Ausdruck exp übereinstimmt。
#match nicht _path
'product_path'.scan /(product)(?!_path)/ #nil
#match nicht _url
'product_path'.scan /(product)(?!_url)/ #product
(?<!exp): Zero-Width Negative Lookbehind Assertion, um zu bestätigen, dass die Position vor diesem Ort nicht mit dem Ausdruck exp übereinstimmt
#match vor name:
'name:angelica'.scan /(?<!name:)(angelica)/ #nil
#match vor nick_name:
'name:angelica'.scan /(?<!nick_name:)(angelica)/#angelica
Der Redakteur ist auch genug von dieser Sache, teile ich wenn ich etwas Gutes habe, heutig waschen und schlafen gehen