perldoc perlre
sagt Folgendes:
(Wenn eine geschweifte Klammer in einem anderen Kontext auftritt und kein Teil bildet einer Backslashed-Sequenz wie
\x{...}
wird sie als regulär behandelt Charakter. Für alle derartigen Warnungen wird jedoch eine Verwarnungswarnung ausgegeben Vorkommen, und in Perl v5.26, wird wörtliche Verwendungen einer geschweiften Klammer Es muss eine Escape-Anweisung sein, z. B. indem Sie ihnen einen Backslash voranstellen ("\{"
) oder umschließen sie in eckigen Klammern ("[{]"
). Dieser Wandel wird zukünftige Syntaxerweiterungen erlauben (wie zum Beispiel die untere Grenze) eines Quantifizierers optional), und bessere Fehlerprüfung von Quantifizierern.)
OK, so dass der folgende Ausdruck die veraltete Nachricht ausgibt.
%Vor%Warum nicht das Folgende?
%Vor% z.B. in der Erfassungsgruppe ist die {
erlaubt unescaped? Wahrscheinlich nicht weil
gibt auch die Warnung aus.
Also, was ist die genaue "Logik"?
P.S .: Ich entkomme jedem buchstabengetreuen {
, frage mich aber, warum es so ist.
Die Warnung wird nur ausgegeben, wenn das lockige:
\b{}
, \B{}
, \g{}
, \k{}
, \N{}
, \o{}
, \p{}
, \P{}
oder \x{}
{n}
, {n,}
oder {n,m}
, wobei n
und m
positive Ganzzahlen Siehe regcomp.c in der Perl-Quelle (die folgende ist von 5.22.0):
%Vor%Demo:
%Vor%Dies ist ein Fehler, entweder in der Dokumentation oder im Regex-Compiler. Ich bin mir nicht sicher, ob das wirklich wichtig ist.
Der Code für die Warnung wurde für eine Situation geschrieben, in der das, was innerhalb der geschweiften Klammern ist, nicht wie \d+(?:,\d+)?
aussieht, aber nicht, wenn vor der öffnenden geschweiften Klammer nichts zu quantifizieren ist
Zum Beispiel akzeptiert es die Klammern als Text und warnt mit etwas wie /x{4x}/
oder /x{4,x}/
, aber warnt nicht für /{3,4}/
, /x({3,4})/
oder /x(a|{3,4})/
Es gibt einen Fehler, bei dem nicht abgesicherte linke Klammern nicht gemeldet wurden. Es ist nicht in einer stabilen Version festgelegt, aber in der aktuellen 5.25-Entwicklungsreihe verfügbar. Stable 5.26, ungefähr im Mai veröffentlicht zu werden, sollte dies behoben haben.
Aber die Dokumentation wurde geklärt, und hier ist es:
%Vor%Blockquote Die einfache Regel, an die du dich erinnern solltest, wenn du willst passe ein literales "{" Zeichen (U + 007B "LINKER LOCKERHALTER") in a an Regular Expression Pattern, ist es, jede literale Instanz davon zu entkommen irgendwie. Im Allgemeinen ist es am einfachsten, es mit einem Backslash, wie "{" oder schließen Sie es in eckige Klammern ("[{]") ein. Wenn das Muster Trennzeichen sind auch Klammern, jede passende rechte Klammer ("}") sollte auch maskiert werden, um den Parser nicht zu verwirren, zum Beispiel
Die Logik besteht darin, die Warnung auszugeben, wenn sich {...}
in einem Kontext befindet, der bedeuten könnte, dass "einige Male übereinstimmen" und nicht ausgegeben wird, wenn dies etwas anderes bedeutet.
Lassen Sie uns {x}
durch {3}
ersetzen und denken Sie an den Regex-Mittelwert.
Ihr erstes Beispiel, /x{3}/
bedeutet Übereinstimmung x
drei Teams: " xxx
"
Ihr letztes Beispiel, /x(x{3})/
, bedeutet Übereinstimmung x
und stimmt dann mit x
dreimal überein und erfasst die Zeichenfolge von 3 x
in einer Gruppe
In /x({3})/
ist die {3}
selbst in einer Capture-Gruppe und bedeutet also "3 mal übereinstimmen". Es bedeutet eindeutig Übereinstimmung x
und stimmt dann mit der literalen Zeichenfolge {3}
überein und fügt sie in eine Erfassungsgruppe ein.