Wie werden nicht erfassende Gruppen, dh (?:)
in regulären Ausdrücken, verwendet und wofür sind sie gut?
regex
capturing-group
regex-group
Never_had_a_name
quelle
quelle
Antworten:
Lassen Sie mich versuchen, dies anhand eines Beispiels zu erklären.
Betrachten Sie den folgenden Text:
Nun, wenn ich den Regex unten darüber anwende ...
... Ich würde folgendes Ergebnis erhalten:
Das Protokoll ist mir jedoch egal - ich möchte nur den Host und den Pfad der URL. Daher ändere ich den regulären Ausdruck so, dass er die nicht erfassende Gruppe enthält
(?:)
.Nun sieht mein Ergebnis so aus:
Sehen? Die erste Gruppe wurde nicht erfasst. Der Parser verwendet es, um den Text abzugleichen, ignoriert ihn jedoch später im Endergebnis.
BEARBEITEN:
Lassen Sie mich auf Wunsch auch versuchen, Gruppen zu erklären.
Nun, Gruppen dienen vielen Zwecken. Sie können Ihnen helfen, genaue Informationen aus einer größeren Übereinstimmung zu extrahieren (die auch benannt werden kann), Sie können eine zuvor übereinstimmende Gruppe erneut abgleichen und sie können für Ersetzungen verwendet werden. Probieren wir einige Beispiele aus.
Stellen Sie sich vor, Sie haben eine Art XML oder HTML (beachten Sie, dass Regex möglicherweise nicht das beste Werkzeug für den Job ist , aber es ist ein gutes Beispiel). Sie möchten die Tags analysieren, damit Sie so etwas tun können (ich habe Leerzeichen hinzugefügt, um das Verständnis zu erleichtern):
Der erste reguläre Ausdruck hat eine benannte Gruppe (TAG), während der zweite eine gemeinsame Gruppe verwendet. Beide regulären Ausdrücke machen dasselbe: Sie verwenden den Wert aus der ersten Gruppe (den Namen des Tags), um mit dem schließenden Tag übereinzustimmen. Der Unterschied besteht darin, dass der erste den Namen verwendet, um mit dem Wert übereinzustimmen, und der zweite den Gruppenindex verwendet (der bei 1 beginnt).
Versuchen wir jetzt einige Substitutionen. Betrachten Sie den folgenden Text:
Lassen Sie uns nun diesen dummen regulären Ausdruck darüber verwenden:
Diese Regex entspricht Wörtern mit mindestens 3 Zeichen und verwendet Gruppen, um die ersten drei Buchstaben zu trennen. Das Ergebnis ist folgendes:
Wenn wir also die Substitutionszeichenfolge anwenden:
... darüber versuchen wir, die erste Gruppe zu verwenden, einen Unterstrich hinzuzufügen, die dritte Gruppe zu verwenden, dann die zweite Gruppe, einen weiteren Unterstrich hinzuzufügen und dann die vierte Gruppe. Die resultierende Zeichenfolge wäre wie die folgende.
Sie können benannte Gruppen auch für Ersetzungen verwenden, indem Sie
${name}
.Um mit Regexes herumzuspielen, empfehle ich http://regex101.com/ , das eine Reihe von Details zur Funktionsweise von Regex bietet. Es bietet auch einige Regex-Engines zur Auswahl.
quelle
Sie können Erfassungsgruppen verwenden, um einen Ausdruck zu organisieren und zu analysieren. Eine nicht erfassende Gruppe hat den ersten Vorteil, aber nicht den Overhead der zweiten. Sie können beispielsweise weiterhin sagen, dass eine nicht erfassende Gruppe optional ist.
Angenommen, Sie möchten mit numerischem Text übereinstimmen, aber einige Zahlen könnten als 1., 2., 3., 4., ... geschrieben werden. Wenn Sie den numerischen Teil erfassen möchten, jedoch nicht das (optionale) Suffix, können Sie eine nicht erfassende Gruppe verwenden .
Das stimmt mit Zahlen in der Form 1, 2, 3 ... oder in der Form 1, 2, 3, ... überein, erfasst aber nur den numerischen Teil.
quelle
?:
wird verwendet, wenn Sie einen Ausdruck gruppieren möchten, ihn jedoch nicht als übereinstimmenden / erfassten Teil der Zeichenfolge speichern möchten.Ein Beispiel wäre etwas, das mit einer IP-Adresse übereinstimmt:
Beachten Sie, dass es mir egal ist, die ersten 3 Oktette zu speichern, aber die
(?:...)
Gruppierung ermöglicht es mir, den regulären Ausdruck zu verkürzen, ohne den Aufwand für das Erfassen und Speichern einer Übereinstimmung zu verursachen.quelle
Dadurch wird die Gruppe nicht erfasst, was bedeutet, dass die von dieser Gruppe übereinstimmende Teilzeichenfolge nicht in die Liste der Erfassungen aufgenommen wird. Ein Beispiel in Rubin, um den Unterschied zu veranschaulichen:
quelle
(?:)
keine Erfassung erstellt wird, und kein nützliches Beispiel dafür zu demonstrieren(?:)
.(?:)
ist nützlich, wenn Sie einen Unterausdruck gruppieren möchten (z. B. wenn Sie Quantifizierer auf einen nichtatomaren Unterausdruck anwenden möchten oder wenn Sie den Umfang von a einschränken möchten|
), aber nichts erfassen möchten.HISTORISCHE MOTIVATION:
Die Existenz nicht erfassender Gruppen kann mit Klammern erklärt werden.
Berücksichtigen Sie die Ausdrücke,
(a|b)c
unda|bc
aufgrund der Priorität der Verkettung|
stehen diese Ausdrücke für zwei verschiedene Sprachen ({ac, bc}
und{a, bc}
jeweils).Die Klammern werden jedoch auch als übereinstimmende Gruppe verwendet (wie in den anderen Antworten erläutert ...).
Wenn Sie eine Klammer haben möchten, aber den Unterausdruck nicht erfassen möchten, verwenden Sie NON-CAPTURING GROUPS. Im Beispiel
(?:a|b)c
quelle
Lassen Sie mich dies anhand eines Beispiels versuchen:
Regex-Code:
(?:animal)(?:=)(\w+)(,)\1\2
Suchbegriff:
Linie 1 -
animal=cat,dog,cat,tiger,dog
Zeile 2 -
animal=cat,cat,dog,dog,tiger
Zeile 3 -
animal=dog,dog,cat,cat,tiger
(?:animal)
-> Nicht erfasste Gruppe 1(?:=)
-> Nicht erfasste Gruppe 2(\w+)
-> Erfasste Gruppe 1(,)
-> Erfasste Gruppe 2\1
-> Ergebnis der erfassten Gruppe 1, dh in Zeile 1 ist Katze, in Zeile 2 ist Katze, in Zeile 3 ist Hund.\2
-> Ergebnis der erfassten Gruppe 2, dh Komma (,)Also in diesem Code durch Geben
\1
und\2
wir erinnern oder wiederholen das Ergebnis der erfassten Gruppe 1 bzw. 2 später im Code.Gemäß der Reihenfolge des Codes
(?:animal)
sollte Gruppe 1 und(?:=)
sollte Gruppe 2 sein und fährt fort ..Aber indem
?:
wir das geben , machen wir die Match-Gruppe nicht erfasst (die in der übereinstimmenden Gruppe nicht zählen, so dass die Gruppierungsnummer von der ersten erfassten Gruppe und nicht von der nicht erfassten Gruppe beginnt), so dass die Wiederholung des Ergebnisses der Match-Gruppe erfolgt(?:animal)
kann später im Code nicht aufgerufen werden.Hoffe, dies erklärt die Verwendung von nicht erfassenden Gruppen.
quelle
Gruppen, die erfasst werden , können Sie später in der Regex verwenden, um sie abzugleichen, ODER Sie können sie im Ersatzteil der Regex verwenden. Wenn Sie eine nicht erfassende Gruppe erstellen, wird diese Gruppe aus einem dieser Gründe einfach von der Verwendung befreit.
Nicht erfassende Gruppen eignen sich hervorragend, wenn Sie versuchen, viele verschiedene Dinge zu erfassen, und es gibt einige Gruppen, die Sie nicht erfassen möchten.
Das ist so ziemlich der Grund, warum sie existieren. Während Sie etwas über Gruppen lernen, lernen Sie etwas über Atomgruppen , sie tun viel! Es gibt auch Lookaround-Gruppen, aber sie sind etwas komplexer und werden nicht so häufig verwendet.
Beispiel für die spätere Verwendung im regulären Ausdruck (Rückreferenz):
<([A-Z][A-Z0-9]*)\b[^>]*>.*?</\1>
[Findet ein XML-Tag (ohne ns-Unterstützung)]([A-Z][A-Z0-9]*)
ist eine Erfassungsgruppe (in diesem Fall der Tagname)Später in der Regex ist,
\1
was bedeutet, dass es nur mit dem gleichen Text übereinstimmt, der in der ersten Gruppe (der([A-Z][A-Z0-9]*)
Gruppe) war (in diesem Fall stimmt es mit dem End-Tag überein ).quelle
Nun, ich bin ein JavaScript-Entwickler und werde versuchen, seine Bedeutung für JavaScript zu erklären.
Stellen Sie sich ein Szenario vor, in dem Sie übereinstimmen möchten,
cat is animal
wenn Sie Katze und Tier zusammenbringen möchten und beide einenis
dazwischen haben sollten.quelle
In komplexen regulären Ausdrücken kann es vorkommen, dass Sie eine große Anzahl von Gruppen verwenden möchten, von denen einige für den Wiederholungsabgleich und einige für die Bereitstellung von Rückverweisen vorgesehen sind. Standardmäßig wird der zu jeder Gruppe passende Text in das Backreference-Array geladen. Wenn wir viele Gruppen haben und nur einige von ihnen aus dem Backreference-Array referenzieren müssen, können wir dieses Standardverhalten überschreiben, um dem regulären Ausdruck mitzuteilen, dass bestimmte Gruppen nur für die Wiederholungsbehandlung vorhanden sind und nicht erfasst und gespeichert werden müssen im Backreference-Array.
quelle
Ich kann die Top-Antworten nicht kommentieren, um Folgendes zu sagen: Ich möchte einen expliziten Punkt hinzufügen, der nur in den Top-Antworten enthalten ist:
Die Nicht-Erfassungsgruppe
(?...)
nicht entfernen nicht alle Zeichen aus dem ursprünglichen vollen Spiel, es nur reorganisiert den Regex optisch an den Programmierer.Um auf einen bestimmten Teil der Regex ohne definierte Fremdzeichen zuzugreifen, müssten Sie immer verwenden
.group(<index>)
quelle
tl; dr nicht-einfangende Gruppen, wie der Name schon sagt sind die Teile der Regex , dass Sie nicht möchten , dass in dem Spiel enthalten sein und
?:
sind eine Möglichkeit , eine Gruppe als nicht-Capturing zu definieren.Angenommen, Sie haben eine E-Mail-Adresse
[email protected]
. Der folgende reguläre Ausdruck erstellt zwei Gruppen , den ID-Teil und den @ example.com-Teil.(\p{Alpha}*[a-z])(@example.com)
. Der Einfachheit halber extrahieren wir den gesamten Domainnamen einschließlich des@
Zeichens.Angenommen, Sie benötigen nur den ID-Teil der Adresse. Was Sie tun möchten, ist, die erste Gruppe des Match-Ergebnisses zu
()
erfassen , die von der Regex umgeben ist, und dies zu tun , indem Sie die nicht erfassende Gruppensyntax verwenden, d?:
. H. Der reguläre Ausdruck(\p{Alpha}*[a-z])(?:@example.com)
gibt also nur den ID-Teil der E-Mail zurück.quelle
Eine interessante Sache, auf die ich gestoßen bin, ist die Tatsache, dass Sie eine Erfassungsgruppe innerhalb einer nicht erfassenden Gruppe haben können. Schauen Sie sich unten den regulären Ausdruck für passende Web-URLs an:
Eingabe-URL-Zeichenfolge:
Die erste Gruppe in meiner regex
(?:([A-Za-z]+):)
ist eine Nicht-Erfassung Gruppe , die das Protokollschema und Doppelpunkt entspricht:
Charakter dhhttp:
aber wenn ich unten Code ausgeführt wurde, war ich den ersten Index des zurückgegebenen Arrays zu sehen , wurde die Zeichenfolge enthält ,http
als ich dachte , dasshttp
und Kolon:
Beide werden nicht gemeldet, da sie sich in einer nicht erfassenden Gruppe befinden.Ich dachte, wenn die erste Gruppe
(?:([A-Za-z]+):)
eine nicht erfassende Gruppe ist, warum gibt sie dann einehttp
Zeichenfolge im Ausgabearray zurück?Wenn Sie also feststellen, dass sich
([A-Za-z]+)
innerhalb der nicht erfassenden Gruppe eine verschachtelte Gruppe befindet. Diese verschachtelte Gruppe([A-Za-z]+)
ist eine Erfassungsgruppe (die?:
am Anfang keine hat ) innerhalb einer nicht erfassenden Gruppe(?:([A-Za-z]+):)
. Aus diesem Grund wird der Texthttp
immer noch erfasst, aber das Doppelpunktzeichen:
, das sich innerhalb der nicht erfassenden Gruppe, aber außerhalb der Erfassungsgruppe befindet, wird nicht im Ausgabearray gemeldet.quelle
Öffnen Sie Ihre Google Chrome devTools und dann die Registerkarte Konsole: und geben Sie Folgendes ein:
Führen Sie es aus und Sie werden sehen:
Die
JavaScript
RegExp-Engine erfasst drei Gruppen, die Elemente mit den Indizes 1,2,3. Verwenden Sie nun die nicht erfassende Markierung, um das Ergebnis anzuzeigen.Das Ergebnis ist:
Dies ist offensichtlich, was eine nicht erfassende Gruppe ist.
quelle
Ich denke, ich würde dir die Antwort geben. Verwenden Sie keine Erfassungsvariablen, ohne zu überprüfen, ob die Übereinstimmung erfolgreich war.
Die Erfassungsvariablen
$1
usw. sind nur gültig, wenn die Übereinstimmung erfolgreich war, und sie werden auch nicht gelöscht.In dem obigen Beispiel zu vermeiden bronto bei der Erfassung
$1
,(?:)
verwendet wird.Wenn das Muster übereinstimmt,
$1
wird es als nächstes gruppiertes Muster erfasst.Die Ausgabe wird also wie folgt sein:
Es ist nützlich, wenn Sie nicht möchten, dass die Übereinstimmungen gespeichert werden.
quelle
Es ist extrem einfach. Wir können anhand eines einfachen Datumsbeispiels verstehen, dass wenn das Datum als 1. Januar 2019 oder 2. Mai 2019 oder ein anderes Datum angegeben wird und wir es einfach in das Format TT / MM / JJJJ konvertieren möchten, würden wir die Monatsdaten nicht benötigen Name, der für diese Angelegenheit Januar oder Februar ist. Um also den numerischen Teil, aber nicht das (optionale) Suffix zu erfassen, können Sie eine nicht erfassende Gruppe verwenden.
so wäre der reguläre Ausdruck,
So einfach ist das.
quelle