Soweit ich weiß, gibt es in JavaScript keine benannten Erfassungsgruppen. Was ist der alternative Weg, um ähnliche Funktionen zu erhalten?
javascript
regex
mmierins
quelle
quelle
Antworten:
ECMAScript 2018 führt benannte Erfassungsgruppen in JavaScript-Regexes ein.
Beispiel:
Wenn Sie ältere Browser unterstützen müssen, können Sie alles mit normalen (nummerierten) Erfassungsgruppen tun, was Sie mit benannten Erfassungsgruppen tun können. Sie müssen nur die Zahlen im Auge behalten - was möglicherweise umständlich ist, wenn die Reihenfolge der Erfassungsgruppe in Ihrer Regex-Änderungen.
Ich kann mir nur zwei "strukturelle" Vorteile benannter Erfassungsgruppen vorstellen:
In einigen Regex-Varianten (.NET und JGSoft, soweit ich weiß) können Sie denselben Namen für verschiedene Gruppen in Ihrer Regex verwenden ( siehe hier für ein Beispiel, wo dies wichtig ist ). Die meisten Regex-Varianten unterstützen diese Funktionalität jedoch ohnehin nicht.
Wenn Sie sich in einer Situation, in der sie von Ziffern umgeben sind, auf nummerierte Erfassungsgruppen beziehen müssen, kann ein Problem auftreten. Angenommen , Sie haben eine Null zu einer Ziffer hinzugefügt werden soll und daher ersetzt werden soll
(\d)
mit$10
. In JavaScript funktioniert dies (solange Sie weniger als 10 Erfassungsgruppen in Ihrem regulären Ausdruck haben), aber Perl wird denken, dass Sie nach einer Referenznummer10
anstelle einer Nummer suchen1
, gefolgt von einer0
. In Perl können Sie${1}0
in diesem Fall verwenden.Ansonsten sind benannte Erfassungsgruppen nur "syntaktischer Zucker". Es ist hilfreich, Erfassungsgruppen nur dann zu verwenden, wenn Sie sie wirklich benötigen, und unter
(?:...)
allen anderen Umständen nicht erfasste Gruppen zu verwenden .Das größere Problem (meiner Meinung nach) mit JavaScript ist, dass es keine ausführlichen regulären Ausdrücke unterstützt, was die Erstellung lesbarer, komplexer regulärer Ausdrücke erheblich erleichtern würde.
Die XRegExp-Bibliothek von Steve Levithan löst diese Probleme.
quelle
Sie können XRegExp verwenden , eine erweiterte, erweiterbare, browserübergreifende Implementierung regulärer Ausdrücke, einschließlich der Unterstützung zusätzlicher Syntax, Flags und Methoden:
s
, damit der Punkt mit allen Zeichen übereinstimmt (auch bekannt als Dotall- oder Singleline-Modus) undx
für freie Abstände und Kommentare (auch als erweiterter Modus bezeichnet).quelle
Eine andere mögliche Lösung: Erstellen Sie ein Objekt, das die Gruppennamen und Indizes enthält.
Verwenden Sie dann die Objektschlüssel, um auf die Gruppen zu verweisen:
Dies verbessert die Lesbarkeit / Qualität des Codes unter Verwendung der Ergebnisse des regulären Ausdrucks, jedoch nicht der Lesbarkeit des regulären Ausdrucks selbst.
quelle
In ES6 können Sie die Array-Destrukturierung verwenden, um Ihre Gruppen abzufangen:
Beachten:
let
überspringt den ersten Wert des resultierenden Arrays, bei dem es sich um die gesamte übereinstimmende Zeichenfolge handelt|| []
nach.exec()
einem Destrukturierung Fehler vermeiden , wenn es keine Übereinstimmungen geben (weil.exec()
zurückkehrennull
)quelle
String.prototype.match
Gibt ein Array zurück mit: der gesamten übereinstimmenden Zeichenfolge an Position 0, danach alle Gruppen danach. Das erste Komma sagt "überspringe das Element an Position 0"RegExp.prototype.exec
überString.prototype.match
an Orten , wo die Zeichenfolge sein kann ,null
oderundefined
.Update: Es hat es endlich in JavaScript geschafft (ECMAScript 2018)!
Benannte Erfassungsgruppen könnten es sehr bald in JavaScript schaffen.
Der Vorschlag dafür befindet sich bereits in Phase 3.
Einer Erfassungsgruppe kann mithilfe der
(?<name>...)
Syntax für jeden Bezeichnernamen ein Name in eckigen Klammern zugewiesen werden. Der reguläre Ausdruck für ein Datum kann dann wie folgt geschrieben werden/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u
. Jeder Name sollte eindeutig sein und der Grammatik für ECMAScript IdentifierName folgen .Auf benannte Gruppen kann über die Eigenschaften einer Gruppeneigenschaft des Ergebnisses des regulären Ausdrucks zugegriffen werden. Ebenso wie für nicht benannte Gruppen werden nummerierte Verweise auf die Gruppen erstellt. Beispielsweise:
quelle
let {year, month, day} = ((result) => ((result) ? result.groups : {}))(re.exec('2015-01-02'));
Die Benennung erfasster Gruppen bietet eines: weniger Verwirrung mit komplexen regulären Ausdrücken.
Es hängt wirklich von Ihrem Anwendungsfall ab, aber vielleicht könnte es hilfreich sein, Ihren regulären Ausdruck hübsch auszudrucken.
Oder Sie können versuchen, Konstanten zu definieren, die auf Ihre erfassten Gruppen verweisen.
Kommentare können dann auch dazu beitragen, anderen, die Ihren Code lesen, zu zeigen, was Sie getan haben.
Im Übrigen muss ich Tims Antwort zustimmen.
quelle
Es gibt eine node.js-Bibliothek namens named-regexp , die Sie in Ihren node.js-Projekten verwenden können (im Browser durch Packen der Bibliothek mit browserify oder anderen Paketskripten). Die Bibliothek kann jedoch nicht mit regulären Ausdrücken verwendet werden, die nicht benannte Erfassungsgruppen enthalten.
Wenn Sie die öffnenden Erfassungsklammern in Ihrem regulären Ausdruck zählen, können Sie eine Zuordnung zwischen benannten Erfassungsgruppen und den nummerierten Erfassungsgruppen in Ihrer Regex erstellen und diese frei mischen und anpassen. Sie müssen nur die Gruppennamen entfernen, bevor Sie den regulären Ausdruck verwenden können. Ich habe drei Funktionen geschrieben, die das demonstrieren. Siehe das Wesentliche: https://gist.github.com/gbirke/2cc2370135b665eee3ef
quelle
Wie Tim Pietzcker sagte, führt ECMAScript 2018 benannte Erfassungsgruppen in JavaScript-Regexes ein. Was ich in den obigen Antworten jedoch nicht gefunden habe, war, wie die benannte erfasste Gruppe im regulären Ausdruck selbst verwendet wird.
Sie können benannte erfasste Gruppen mit folgender Syntax verwenden :
\k<name>
. beispielsweiseund wie Forivin sagte, können Sie die erfasste Gruppe im Objektergebnis wie folgt verwenden:
quelle
Während Sie dies mit Vanille-JavaScript nicht tun können, können Sie möglicherweise eine
Array.prototype
Funktion verwendenArray.prototype.reduce
, um indizierte Übereinstimmungen mit etwas Magie in benannte Übereinstimmungen umzuwandeln .Für die folgende Lösung müssen die Übereinstimmungen natürlich in der richtigen Reihenfolge erfolgen:
quelle
var assocArray = Regex("hello alex, I am dennis", "hello ({hisName}.+), I am ({yourName}.+)");
RegExp
Objekt erweitern, indem Sie seinem Prototyp eine Funktion hinzufügen.Sie haben kein ECMAScript 2018?
Mein Ziel war es, es so ähnlich wie möglich zu machen, wie wir es von benannten Gruppen gewohnt sind. Während Sie in ECMAScript 2018
?<groupname>
innerhalb der Gruppe eine benannte Gruppe angeben können, können Sie in meiner Lösung für älteres Javascript(?!=<groupname>)
innerhalb der Gruppe platzieren, um dasselbe zu tun. Es ist also ein zusätzlicher Satz Klammern und ein zusätzlicher!=
. Ziemlich knapp!Ich habe alles in eine String-Prototyp-Funktion eingewickelt
Eigenschaften
Anleitung
(?!={groupname})
innerhalb jeder Gruppe, die Sie benennen möchten()
indem Sie sie?:
an den Anfang dieser Gruppe setzen. Diese werden nicht benannt.arrays.js
Verwendung
Ergebnis von o
quelle