it-swarm.com.de

Warum gibt mir der Alternationsoperator (Pipe) (|) in regulären Ausdrücken in JavaScript keine zwei Übereinstimmungen?

Hier ist mein regulärer Ausdruck:

"button:not([DISABLED])".match(/\([^()]+\)|[^()]+/g);

Das Ergebnis ist:

["button:not", "([DISABLED])"]

Ist es richtig? Ich bin verwirrt. Weil der (Pipe-) Operator | bedeutet "oder", ich denke das richtige Ergebnis ist:

["button:not", "[DISABLED]", "([DISABLED])"] 

Weil das:

["button:not", "[DISABLED]"]

ist das Ergebnis von:

"button:not([DISABLED])".match(/[^()]+/g);

und das:

["([DISABLED])"]

ist das Ergebnis von:

"button:not([DISABLED])".match(/\([^()]+\)/g);

Aber die Ergebnisausgabe in der Konsole sagt mir, dass das Ergebnis ist:

["button:not", "([DISABLED])"]

Wo ist das Problem?

36
user2155362

Der Regex

/\([^()]+\)|[^()]+/g

Grundsätzlich gilt: Es gibt zwei Optionen, match (1) \([^()]+\) oder (2) [^()]+, wo immer Sie eine davon sehen (/g).

Lassen Sie uns an Ihrer Beispielzeichenfolge iterieren, damit Sie den Grund hinter dem erhaltenen Ergebnis verstehen.

Anfangszeichenfolge: button:not([DISABLED]).

  • Der Cursor beginnt am Zeichenb (Eigentlich beginnt es am Stringanfangsanker, ^, aber für dieses Beispiel ist es irrelevant.).
  • Zwischen den beiden verfügbaren Optionen kannbnur mit (2) übereinstimmen, da für (1) ein Startcode(.
    • Jetzt, da es begonnen hat, mit dem (2) übereinzustimmen, wird es den ganzen Weg durchlaufen, was bedeutet, dass es alles verbraucht, was kein(oder)ist.
    • Ab dem obigen Punkt verbraucht es alles bis zutchar (da das nächste ein(ist und nicht mit [^()]+ übereinstimmt), wodurchbutton:not verlassen wird als erste übereinstimmende Zeichenfolge .
  • (Raum für Klarheit)
  • Jetzt steht der Cursor auf(. Fängt es an, mit einer der Optionen übereinzustimmen? Ja, der erste: \([^()]+\).
    • Nun, da es begonnen hat, das (1) abzugleichen, wird es den ganzen Weg durchlaufen, was bedeutet, dass es alles verbraucht, was kein(oder) bis es findet einen) (Wenn es beim Konsumieren einen(vor einem)findet, wird zurückverfolgt, da dies bedeutet, dass der (1) reguläre Ausdruck letztendlich nicht übereinstimmt.).
    • Jetzt verbraucht es alle verbleibenden Zeichen, bis es), findet und dann ([DISABLED]) als zweite übereinstimmende Zeichenfolge zurücklässt.
  • (Raum für Klarheit)
  • Da wir das letzte Zeichen erreicht haben, endet die Regex-Verarbeitung.



Bearbeiten: Es gibt ein sehr nützliches Online-Tool , mit dem Sie den regulären Ausdruck in grafischer Form anzeigen können. Vielleicht hilft es zu verstehen, wie der reguläre Ausdruck funktioniert:

Regular expression image

Sie können den Cursor auch Schritt für Schritt bewegen und sehen, was ich oben erklärt habe:live link.

Hinweis zur Priorität von durch | getrennten Ausdrücken: Aufgrund der Art und Weise, wie die JavaScript-Regex-Engine die Zeichenfolgen verarbeitet, spielt die Reihenfolge, in der die Ausdrücke angezeigt werden, eine Rolle. Jede Alternative wird in der angegebenen Reihenfolge bewertet. Wenn eine dieser Optionen bis zum Ende übereinstimmt, wird nicht versucht, eine andere Option zuzuordnen, auch wenn dies möglich ist. Hoffentlich macht ein Beispiel es klarer:

"aaa".match(/a|aa|aaa/g); // ==> ["a", "a", "a"]
"aaa".match(/aa|aaa|a/g); // ==> ["aa", "a"]
"aaa".match(/aaa|a|aa/g); // ==> ["aaa"]
55
acdcjunior

Ihr Verständnis des Wechseloperators scheint falsch zu sein. Es wird nicht nach alles möglichen Übereinstimmungen gesucht, sondern nur nach zuerst Übereinstimmungen (von links nach rechts).

Erwägen (a | b) als "Übereinstimmung entweder a oder b ".

Siehe auch: http://www.regular-expressions.info/alternation.html

14
Felix Kling

Ich verstehe mich mit regulären Ausdrücken nicht sehr gut, aber ich denke, sie funktionieren, indem sie Ihnen eine Sache geben, die zu ihnen passt, und nicht alle Dinge, die zu ihnen passen könnten.

Also, die | Operator sagt: "Gib mir etwas, das mit dem linken regulären Ausdruck übereinstimmt, oder etwas, das mit dem rechten regulären Ausdruck übereinstimmt".

Da Ihre Zeichenfolge etwas enthält, das mit dem linken regulären Ausdruck übereinstimmt, erhalten Sie nur das.

0
Paul D. Waite