Modifizierte ECMAScript-Reguläre-Ausdrucks-Grammatik
Diese Seite beschreibt die Reguläre-Ausdrucks-Grammatik, die verwendet wird, wenn std::basic_regex mit syntax_option_type auf ECMAScript (Standard) gesetzt konstruiert wird. Andere unterstützte Reguläre-Ausdrucks-Grammatiken finden Sie unter syntax_option_type.
Die ECMAScript 3 Reguläre-Ausdrucks-Grammatik in C++ ist die ECMA-262 Grammatik mit den nachfolgend mit (nur C++) markierten Modifikationen.
Inhalt |
[bearbeiten] Übersicht
Die modifizierte Reguläre-Ausdrucks-Grammatik ist größtenteils die ECMAScript RegExp-Grammatik mit einer POSIX-artigen Erweiterung für Locales unter ClassAtom. Einige Klarstellungen zu Gleichheitsprüfungen und Zahlenparsing sind vorgenommen. Für viele der hier gezeigten Beispiele können Sie diese Äquivalenz in Ihrer Browserkonsole ausprobieren.
function match(s, re) { return s.match(new RegExp(re)); }
Die "normativen Referenzen" im Standard spezifizieren ECMAScript 3. Wir verweisen hier auf die ECMAScript 5.1 Spezifikation, da diese nur geringfügige Änderungen gegenüber ECMAScript 3 aufweist und auch als HTML-Version verfügbar ist. Eine Übersicht über die Dialektmerkmale finden Sie im MDN Guide zu JavaScript RegExp.
[bearbeiten] Alternativen
Ein Regulärer-Ausdrucks-Muster ist eine Folge von einer oder mehreren Alternativen, getrennt durch den Disjunktionsoperator | (mit anderen Worten, der Disjunktionsoperator hat die niedrigste Priorität).
Muster ::
- Disjunktion
Disjunktion ::
- Alternative
- Alternative
|Disjunktion
Das Muster versucht zuerst, die Disjunktion zu überspringen und die linke Alternative gefolgt vom Rest des Regulären Ausdrucks (nach der Disjunktion) abzugleichen.
Wenn dies fehlschlägt, versucht es, die linke Alternative zu überspringen und die rechte Disjunktion (gefolgt vom Rest des Regulären Ausdrucks) abzugleichen.
Wenn die linke Alternative, die rechte Disjunktion und der Rest des Regulären Ausdrucks alle Wahlpunkte haben, werden alle Wahlmöglichkeiten im Rest des Ausdrucks ausprobiert, bevor zur nächsten Wahlmöglichkeit in der linken Alternative übergegangen wird. Wenn die Wahlmöglichkeiten in der linken Alternative erschöpft sind, wird stattdessen die rechte Disjunktion ausprobiert.
Jegliche Erfassungsklammern innerhalb einer übersprungenen Alternative erzeugen leere Teilübereinstimmungen.
#include <cstddef> #include <iostream> #include <regex> #include <string> void show_matches(const std::string& in, const std::string& re) { std::smatch m; std::regex_search(in, m, std::regex(re)); if (!m.empty()) { std::cout << "input=[" << in << "], regex=[" << re << "]\n " "prefix=[" << m.prefix() << "]\n smatch: "; for (std::size_t n = 0; n < m.size(); ++n) std::cout << "m[" << n << "]=[" << m[n] << "] "; std::cout << "\n suffix=[" << m.suffix() << "]\n"; } else std::cout << "input=[" << in << "], regex=[" << re << "]: NO MATCH\n"; } int main() { show_matches("abcdef", "abc|def"); show_matches("abc", "ab|abc"); // left Alternative matched first // Match of the input against the left Alternative (a) followed // by the remained of the regex (c|bc) succeeds, which results // in m[1]="a" and m[4]="bc". // The skipped Alternatives (ab) and (c) leave their submatches // m[3] and m[5] empty. show_matches("abc", "((a)|(ab))((c)|(bc))"); }
Ausgabe
input=[abcdef], regex=[abc|def] prefix=[] smatch: m[0]=[abc] suffix=[def] input=[abc], regex=[ab|abc] prefix=[] smatch: m[0]=[ab] suffix=[c] input=[abc], regex=[((a)|(ab))((c)|(bc))] prefix=[] smatch: m[0]=[abc] m[1]=[a] m[2]=[a] m[3]=[] m[4]=[bc] m[5]=[] m[6]=[bc] suffix=[]
[bearbeiten] Terme
Jede Alternative ist entweder leer oder eine Folge von Termen (ohne Trennzeichen zwischen den Termen)
Alternative ::
- [leer]
- Alternative Term
Eine leere Alternative stimmt immer überein und verbraucht keine Eingabe.
Aufeinanderfolgende Terme versuchen gleichzeitig, aufeinanderfolgende Teile der Eingabe abzugleichen.
Wenn die linke Alternative, der rechte Term und der Rest des Regulären Ausdrucks alle Wahlpunkte haben, werden alle Wahlmöglichkeiten im Rest des Ausdrucks ausprobiert, bevor zur nächsten Wahlmöglichkeit im rechten Term übergegangen wird, und alle Wahlmöglichkeiten im rechten Term werden ausprobiert, bevor zur nächsten Wahlmöglichkeit in der linken Alternative übergegangen wird.
#include <cstddef> #include <iostream> #include <regex> #include <string> void show_matches(const std::string& in, const std::string& re) { std::smatch m; std::regex_search(in, m, std::regex(re)); if (!m.empty()) { std::cout << "input=[" << in << "], regex=[" << re << "]\n " "prefix=[" << m.prefix() << "]\n smatch: "; for (std::size_t n = 0; n < m.size(); ++n) std::cout << "m[" << n << "]=[" << m[n] << "] "; std::cout << "\n suffix=[" << m.suffix() << "]\n"; } else std::cout << "input=[" << in << "], regex=[" << re << "]: NO MATCH\n"; } int main() { show_matches("abcdef", ""); // empty regex is a single empty Alternative show_matches("abc", "abc|"); // left Alternative matched first show_matches("abc", "|abc"); // left Alternative matched first, leaving abc unmatched }
Ausgabe
input=[abcdef], regex=[] prefix=[] smatch: m[0]=[] suffix=[abcdef] input=[abc], regex=[abc|] prefix=[] smatch: m[0]=[abc] suffix=[] input=[abc], regex=[|abc] prefix=[] smatch: m[0]=[] suffix=[abc]
[bearbeiten] Quantifizierer
- Jeder Term ist entweder eine Assertion (siehe unten) oder ein Atom (siehe unten) oder ein Atom, gefolgt von einem Quantifizierer
Term ::
- Assertion
- Atom
- Atom Quantifizierer
Jeder Quantifizierer ist entweder ein gieriger Quantifizierer (der nur aus einem QuantifierPrefix besteht) oder ein nicht-gieriger Quantifizierer (der aus einem QuantifierPrefix gefolgt von einem Fragezeichen ? besteht).
Quantifizierer ::
- QuantifierPrefix
- QuantifierPrefix
?
Jeder QuantifierPrefix bestimmt zwei Zahlen: die minimale und die maximale Anzahl von Wiederholungen, wie folgt:
| QuantifierPrefix | Minimum | Maximum |
|---|---|---|
*
|
null | infinity |
+
|
eins | infinity |
?
|
null | eins |
{ DezimalZiffern } |
Wert von DezimalZiffern | Wert von DezimalZiffern |
{ DezimalZiffern , } |
Wert von DezimalZiffern | infinity |
{ DezimalZiffern , DezimalZiffern } |
Wert von DezimalZiffern vor dem Komma | Wert von DezimalZiffern nach dem Komma |
Die Werte der einzelnen DezimalZiffern werden durch Aufrufen von std::regex_traits::value(nur C++) für jede der Ziffern ermittelt.
Ein Atom gefolgt von einem Quantifizierer wird so oft wiederholt, wie es der Quantifizierer angibt. Ein Quantifizierer kann nicht-gierig sein, in diesem Fall wird das Atom-Muster so wenig wie möglich wiederholt, während es noch den Rest des Regulären Ausdrucks abgleicht, oder er kann gierig sein, in diesem Fall wird das Atom-Muster so oft wie möglich wiederholt, während es noch den Rest des Regulären Ausdrucks abgleicht.
Das Atom-Muster ist das, was wiederholt wird, nicht die Eingabe, die es abgleicht, sodass verschiedene Wiederholungen des Atoms unterschiedliche Eingabe-Teilstrings abgleichen können.
Wenn das Atom und der Rest des Regulären Ausdrucks alle Wahlpunkte haben, wird das Atom zuerst so oft wie möglich (oder so wenig wie möglich, wenn nicht-gierig) abgeglichen. Alle Wahlmöglichkeiten im Rest des Regulären Ausdrucks werden ausprobiert, bevor zur nächsten Wahlmöglichkeit in der letzten Wiederholung des Atoms übergegangen wird. Alle Wahlmöglichkeiten in der letzten (n-ten) Wiederholung des Atoms werden ausprobiert, bevor zur nächsten Wahlmöglichkeit in der vorletzten (n-1-ten) Wiederholung des Atoms übergegangen wird; an diesem Punkt kann sich herausstellen, dass mehr oder weniger Wiederholungen des Atoms nun möglich sind; diese werden erschöpft (wiederum beginnend mit entweder so wenigen oder so vielen wie möglich), bevor zur nächsten Wahlmöglichkeit in der (n-1-ten) Wiederholung des Atoms usw. übergegangen wird.
Die Erfassungen des Atoms werden jedes Mal gelöscht, wenn es wiederholt wird (siehe das Beispiel "(z)((a+)?(b+)?(c))*" unten).
#include <cstddef> #include <iostream> #include <regex> #include <string> void show_matches(const std::string& in, const std::string& re) { std::smatch m; std::regex_search(in, m, std::regex(re)); if (!m.empty()) { std::cout << "input=[" << in << "], regex=[" << re << "]\n " "prefix=[" << m.prefix() << "]\n smatch: "; for (std::size_t n = 0; n < m.size(); ++n) std::cout << "m[" << n << "]=[" << m[n] << "] "; std::cout << "\n suffix=[" << m.suffix() << "]\n"; } else std::cout << "input=[" << in << "], regex=[" << re << "]: NO MATCH\n"; } int main() { // greedy match, repeats [a-z] 4 times show_matches("abcdefghi", "a[a-z]{2,4}"); // non-greedy match, repeats [a-z] 2 times show_matches("abcdefghi", "a[a-z]{2,4}?"); // Choice point ordering for quantifiers results in a match // with two repetitions, first matching the substring "aa", // second matching the substring "ba", leaving "ac" not matched // ("ba" appears in the capture clause m[1]) show_matches("aabaac", "(aa|aabaac|ba|b|c)*"); // Choice point ordering for quantifiers makes this regex // calculate the greatest common divisor between 10 and 15 // (the answer is 5, and it populates m[1] with "aaaaa") show_matches("aaaaaaaaaa,aaaaaaaaaaaaaaa", "^(a+)\\1*,\\1+$"); // the substring "bbb" does not appear in the capture clause m[4] // because it is cleared when the second repetition of the atom // (a+)?(b+)?(c) is matching the substring "ac" // NOTE: gcc gets this wrong - it does not correctly clear the // matches[4] capture group as required by ECMA-262 21.2.2.5.1, // and thus incorrectly captures "bbb" for that group. show_matches("zaacbbbcac", "(z)((a+)?(b+)?(c))*"); }
Ausgabe
input=[abcdefghi], regex=[a[a-z]{2,4}]
prefix=[]
smatch: m[0]=[abcde]
suffix=[fghi]
input=[abcdefghi], regex=[a[a-z]{2,4}?]
prefix=[]
smatch: m[0]=[abc]
suffix=[defghi]
input=[aabaac], regex=[(aa|aabaac|ba|b|c)*]
prefix=[]
smatch: m[0]=[aaba] m[1]=[ba]
suffix=[ac]
input=[aaaaaaaaaa,aaaaaaaaaaaaaaa], regex=[^(a+)\1*,\1+$]
prefix=[]
smatch: m[0]=[aaaaaaaaaa,aaaaaaaaaaaaaaa] m[1]=[aaaaa]
suffix=[]
input=[zaacbbbcac], regex=[(z)((a+)?(b+)?(c))*]
prefix=[]
smatch: m[0]=[zaacbbbcac] m[1]=[z] m[2]=[ac] m[3]=[a] m[4]=[] m[5]=[c]
suffix=[][bearbeiten] Assertionen
Assertionen gleichen Bedingungen ab, nicht Eingabe-Teilstrings. Sie verbrauchen nie Zeichen aus der Eingabe. Jede Assertion ist eine der folgenden:
Assertion ::
-
^ -
$ -
\b -
\B -
(?=Disjunktion) -
(?!Disjunktion)
Die Assertion ^ (Zeilenanfang) stimmt überein
Die Assertion $ (Zeilenende) stimmt überein
In den beiden obigen Assertionen und im Atom . unten ist LineTerminator eines der folgenden vier Zeichen: U+000A (\n oder Zeilenvorschub), U+000D (\r oder Wagenrücklauf), U+2028 (Zeilenseparator) oder U+2029 (Absatzseparator).
Die Assertion \b (Wortgrenze) stimmt überein
Die Assertion \B (negative Wortgrenze) stimmt mit allem überein AUSSER dem Folgenden:
Die Assertion ( ? = Disjunktion ) (nullbreite positive Vorwärtsprüfung) stimmt überein, wenn Disjunktion die Eingabe an der aktuellen Position abgleichen würde.
Die Assertion ( ? ! Disjunktion ) (nullbreite negative Vorwärtsprüfung) stimmt überein, wenn Disjunktion die Eingabe an der aktuellen Position NICHT abgleichen würde.
Bei beiden Lookahead-Assertionen wird bei der Abgleichung der Disjunktion die Position nicht vor dem Abgleich des restlichen Regulären Ausdrucks vorgerückt. Außerdem wird, wenn Disjunktion an der aktuellen Position auf verschiedene Weisen übereinstimmen kann, nur die erste ausprobiert.
ECMAScript verbietet Backtracking in die Lookahead-Disjunktionen, was das Verhalten von Rückverweisen in eine positive Lookahead vom Rest des Regulären Ausdrucks aus beeinflusst (siehe Beispiel unten). Rückverweise in die negative Lookahead vom Rest des Regulären Ausdrucks sind immer undefiniert (da die Lookahead-Disjunktion fehlschlagen muss, um fortzufahren).
Hinweis: Lookahead-Assertionen können verwendet werden, um eine logische UND-Verknüpfung zwischen mehreren Regulären Ausdrücken zu erstellen (siehe Beispiel unten).
#include <cstddef> #include <iostream> #include <regex> #include <string> void show_matches(const std::string& in, const std::string& re) { std::smatch m; std::regex_search(in, m, std::regex(re)); if (!m.empty()) { std::cout << "input=[" << in << "], regex=[" << re << "]\n " "prefix=[" << m.prefix() << "]\n smatch: "; for (std::size_t n = 0; n < m.size(); ++n) std::cout << "m[" << n << "]=[" << m[n] << "] "; std::cout << "\n suffix=[" << m.suffix() << "]\n"; } else std::cout << "input=[" << in << "], regex=[" << re << "]: NO MATCH\n"; } int main() { // matches the a at the end of input show_matches("aaa", "a$"); // matches the o at the end of the first word show_matches("moo goo gai pan", "o\\b"); // the lookahead matches the empty string immediately after the first b // this populates m[1] with "aaa" although m[0] is empty show_matches("baaabac", "(?=(a+))"); // because backtracking into lookaheads is prohibited, // this matches aba rather than aaaba show_matches("baaabac", "(?=(a+))a*b\\1"); // logical AND via lookahead: this password matches IF it contains // at least one lowercase letter // AND at least one uppercase letter // AND at least one punctuation character // AND be at least 6 characters long show_matches("abcdef", "(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}"); show_matches("aB,def", "(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}"); }
Ausgabe
input=[aaa], regex=[a$]
prefix=[aa]
smatch: m[0]=[a]
suffix=[]
input=[moo goo gai pan], regex=[o\b]
prefix=[mo]
smatch: m[0]=[o]
suffix=[ goo gai pan]
input=[baaabac], regex=[(?=(a+))]
prefix=[b]
smatch: m[0]=[] m[1]=[aaa]
suffix=[aaabac]
input=[baaabac], regex=[(?=(a+))a*b\1]
prefix=[baa]
smatch: m[0]=[aba] m[1]=[a]
suffix=[c]
input=[abcdef], regex=[(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}]: NO MATCH
input=[aB,def], regex=[(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}]
prefix=[]
smatch: m[0]=[aB,def]
suffix=[][bearbeiten] Atome
Ein Atom kann eines der folgenden sein:
Atom ::
- PatternCharacter
-
. -
\AtomEscape - CharacterClass
-
(Disjunktion) -
(?:Disjunktion)
wobei AtomEscape:
- DecimalEscape
- CharacterEscape
- CharacterClassEscape
Unterschiedliche Arten von Atomen werden unterschiedlich ausgewertet.
[bearbeiten] Unterdrücke
Das Atom ( Disjunktion ) ist ein markierter Unterdruck: Es wertet die Disjunktion aus und speichert die Kopie des von der Disjunktion konsumierten Eingabe-Teilstrings im Teilübereinstimmungs-Array unter dem Index, der der Anzahl der bisher im gesamten Regulären Ausdruck aufgetretenen linken öffnenden Klammern ( von markierten Unterdrücken entspricht.
Neben der Rückgabe in std::match_results sind die erfassten Teilübereinstimmungen als Rückverweise (\1, \2, ...) zugänglich und können in Regulären Ausdrücken referenziert werden. Beachten Sie, dass std::regex_replace $ anstelle von \ für Rückverweise ($1, $2, ...) auf dieselbe Weise wie String.prototype.replace (ECMA-262, Teil 15.5.4.11) verwendet.
Das Atom ( ? : Disjunktion ) (nicht-markierender Unterdruck) wertet einfach die Disjunktion aus und speichert deren Ergebnisse nicht in der Teilübereinstimmung. Dies ist eine rein lexikalische Gruppierung.
| Dieser Abschnitt ist unvollständig Grund: kein Beispiel |
[bearbeiten] Rückverweise
DecimalEscape ::
- DecimalIntegerLiteral [lookahead ∉ DecimalDigit]
Wenn \ von einer Dezimalzahl N gefolgt wird, deren erste Ziffer keine 0 ist, dann wird die Escape-Sequenz als Rückverweis betrachtet. Der Wert N wird durch Aufrufen von std::regex_traits::value(nur C++) für jede der Ziffern und deren Kombination mittels Basis-10-Arithmetik ermittelt. Es ist ein Fehler, wenn N größer ist als die Gesamtzahl der linken Erfassungsklammern im gesamten Regulären Ausdruck.
Wenn ein Rückverweis \N als Atom erscheint, stimmt er mit demselben Teilstring überein, der aktuell im N-ten Element des Teilübereinstimmungs-Arrays gespeichert ist.
Die Dezimal-Escape-Sequenz \0 ist KEIN Rückverweis: Sie ist eine Zeichen-Escape-Sequenz, die das NUL-Zeichen darstellt. Sie darf nicht von einer Dezimalziffer gefolgt werden.
Wie oben erwähnt, beachte, dass std::regex_replace $ anstelle von \ für Rückverweise ($1, $2, ...) verwendet.
| Dieser Abschnitt ist unvollständig Grund: kein Beispiel |
[bearbeiten] Einzelzeichen-Übereinstimmungen
Das Atom . stimmt mit einem beliebigen Zeichen aus dem Eingabe-String überein und verbraucht es, außer LineTerminator (U+000D, U+000A, U+2029 oder U+2028).
Das Atom PatternCharacter, wobei PatternCharacter ein beliebiges SourceCharacter AUSSER den Zeichen ^ $ \ . * + ? ( ) [ ] { } | ist, stimmt mit einem Zeichen aus der Eingabe überein und verbraucht es, wenn es mit diesem PatternCharacter übereinstimmt.
Die Gleichheit für diese und alle anderen Einzelzeichen-Übereinstimmungen ist wie folgt definiert:
Jedes Atom, das aus dem Escape-Zeichen \ gefolgt von CharacterEscape besteht, sowie die spezielle DecimalEscape \0, stimmt mit einem Zeichen aus der Eingabe überein und verbraucht es, wenn es mit dem durch die CharacterEscape dargestellten Zeichen übereinstimmt. Die folgenden Zeichen-Escape-Sequenzen werden erkannt:
CharacterEscape ::
- ControlEscape
-
cControlLetter - HexEscapeSequence
- UnicodeEscapeSequence
- IdentityEscape
Hier ist ControlEscape eines der folgenden fünf Zeichen: f n r t v
| ControlEscape | Code Unit | Name |
|---|---|---|
f
|
U+000C | Form Feed |
n
|
U+000A | Neue Zeile |
r
|
U+000D | Wagenrücklauf |
t
|
U+0009 | Horizontaler Tabulator |
v
|
U+000B | Vertikaler Tabulator |
ControlLetter ist ein beliebiger Klein- oder Großbuchstabe des ASCII-Alphabets und diese Zeichen-Escape-Sequenz entspricht dem Zeichen, dessen Code-Einheit den Restwert der Division der Code-Einheit von ControlLetter durch 32 ist. Zum Beispiel entspricht \cD und \cd beide der Code-Einheit U+0004 (EOT), da 'D' U+0044 ist und 0x44 % 32 == 4, und 'd' U+0064 ist und 0x64 % 32 == 4.
HexEscapeSequence ist der Buchstabe x gefolgt von genau zwei HexDigits (wobei HexDigit eine der folgenden ist: 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F). Diese Zeichen-Escape-Sequenz entspricht dem Zeichen, dessen Code-Einheit dem numerischen Wert der zweistelligen Hexadezimalzahl entspricht.
UnicodeEscapeSequence ist der Buchstabe u gefolgt von genau vier HexDigits. Diese Zeichen-Escape-Sequenz entspricht dem Zeichen, dessen Code-Einheit dem numerischen Wert dieser vierstelligen Hexadezimalzahl entspricht. Wenn der Wert nicht in den CharT von std::basic_regex passt, wird std::regex_error ausgelöst (nur C++).
IdentityEscape kann jedes nicht-alphanumerische Zeichen sein: zum Beispiel ein weiteres Backslash. Es stimmt mit dem Zeichen wie es ist überein.
#include <cstddef> #include <iostream> #include <regex> #include <string> void show_matches(const std::wstring& in, const std::wstring& re) { std::wsmatch m; std::regex_search(in, m, std::wregex(re)); if (!m.empty()) { std::wcout << L"input=[" << in << L"], regex=[" << re << L"]\n " L"prefix=[" << m.prefix() << L"]\n wsmatch: "; for (std::size_t n = 0; n < m.size(); ++n) std::wcout << L"m[" << n << L"]=[" << m[n] << L"] "; std::wcout << L"\n suffix=[" << m.suffix() << L"]\n"; } else std::wcout << L"input=[" << in << "], regex=[" << re << L"]: NO MATCH\n"; } int main() { // Most escapes are similar to C++, save for metacharacters. You will have to // double-escape or use raw strings on the slashes though. show_matches(L"C++\\", LR"(C\+\+\\)"); // Escape sequences and NUL. std::wstring s(L"ab\xff\0cd", 5); show_matches(s, L"(\\0|\\u00ff)"); // No matching for non-BMP Unicode is defined, because ECMAScript uses UTF-16 // atoms. Whether this emoji banana matches can be platform dependent: // These need to be wide-strings! show_matches(L"\U0001f34c", L"[\\u0000-\\ufffe]+"); }
Mögliche Ausgabe
input=[C++\], regex=[C\+\+\\]
prefix=[]
wsmatch: m[0]=[C++\]
suffix=[]
input=[ab?c], regex=[(\0{{!}}\u00ff)]
prefix=[ab]
wsmatch: m[0]=[?] m[1]=[?]
suffix=[c]
input=[?], regex=[[\u0000-\ufffe]+]: NO MATCH
[bearbeiten] Zeichenklassen
Ein Atom kann eine Zeichenklasse darstellen, d.h. es stimmt mit einem Zeichen überein und verbraucht es, wenn es zu einer der vordefinierten Gruppen von Zeichen gehört.
Eine Zeichenklasse kann durch eine Zeichenklassen-Escape-Sequenz eingeführt werden:
Atom ::
-
\CharacterClassEscape
oder direkt:
Atom ::
- CharacterClass
Die Zeichenklassen-Escape-Sequenzen sind Kurzformen für einige gängige Zeichenklassen, wie folgt:
| CharacterClassEscape | Klassenname Ausdruck(nur C++) | Bedeutung |
|---|---|---|
d
|
[[:digit:]]
|
digits |
D
|
[^[:digit:]]
|
Nicht-Ziffern |
s
|
[[:space:]]
|
Leerzeichen-Zeichen |
S
|
[^[:space:]]
|
Nicht-Leerzeichen-Zeichen |
w
|
[_[:alnum:]]
|
Alphanumerische Zeichen und das Zeichen _ |
W
|
[^_[:alnum:]]
|
Zeichen außer alphanumerischen oder _ |
Eine CharacterClass ist eine von eckigen Klammern umschlossene Sequenz von ClassRanges, die optional mit dem Negationsoperator ^ beginnt. Wenn sie mit ^ beginnt, stimmt dieses Atom mit jedem Zeichen überein, das NICHT in der durch die Vereinigung aller ClassRanges dargestellten Zeichenmenge enthalten ist. Andernfalls stimmt dieses Atom mit jedem Zeichen überein, das in der durch die Vereinigung aller ClassRanges dargestellten Zeichenmenge ENTHALTEN ist.
CharacterClass ::
-
[[Lookahead ∉ {^}] ClassRanges] -
[^ClassRanges]
ClassRanges :
- [leer]
- NonemptyClassRanges
NonemptyClassRanges ::
- ClassAtom
- ClassAtom NonemptyClassRangesNoDash
- ClassAtom - ClassAtom ClassRanges
Wenn ein nicht-leerer Klassenbereich die Form ClassAtom - ClassAtom hat, stimmt er mit jedem Zeichen aus einem Bereich überein, der wie folgt definiert ist: (nur C++)
Der erste ClassAtom muss ein einzelnes Kollationselement c1 abgleichen und der zweite ClassAtom muss ein einzelnes Kollationselement c2 abgleichen. Um zu prüfen, ob das Eingabezeichen c von diesem Bereich abgeglichen wird, werden folgende Schritte unternommen:
c stimmt überein, wenn c1 <= c && c <= c2.c, c1 und c2) an std::regex_traits::translate_nocase übergeben.c, c1 und c2) an std::regex_traits::translate übergeben.c stimmt überein, wenn transformed c1 <= transformed c && transformed c <= transformed c2.Das Zeichen - wird wörtlich behandelt, wenn es
- das erste oder letzte Zeichen von ClassRanges ist
- der Anfang oder das Ende eines durch Bindestrich getrennten Bereichs von ClassAtom ist
- direkt nach einem durch Bindestrich getrennten Bereich folgt.
- mit einem Backslash als CharacterEscape maskiert ist.
NonemptyClassRangesNoDash :
- ClassAtom
- ClassAtomNoDash NonemptyClassRangesNoDash
- ClassAtomNoDash - ClassAtom ClassRanges
ClassAtom ::
-
- - ClassAtomNoDash
- ClassAtomExClass(nur C++)
- ClassAtomCollatingElement(nur C++)
- ClassAtomEquivalence(nur C++)
ClassAtomNoDash :
- SourceCharacter, aber nicht
\,]oder- -
\ClassEscape
Jedes ClassAtomNoDash repräsentiert ein einzelnes Zeichen -- entweder SourceCharacter direkt oder wie folgt maskiert:
ClassEscape :
- DecimalEscape
-
b - CharacterEscape
- CharacterClassEscape
Die spezielle ClassEscape \b erzeugt eine Zeichenmenge, die die Code-Einheit U+0008 (Backspace) abgleicht. Außerhalb von CharacterClass ist es die Assertion für Wortgrenzen.
Die Verwendung von \B und die Verwendung jedes Rückverweises (DecimalEscape außer Null) innerhalb einer CharacterClass ist ein Fehler.
Die Zeichen - und ] müssen möglicherweise in einigen Situationen maskiert werden, um als Atome behandelt zu werden. Andere Zeichen, die außerhalb von CharacterClass eine besondere Bedeutung haben, wie * oder ?, müssen nicht maskiert werden.
| Dieser Abschnitt ist unvollständig Grund: kein Beispiel |
[bearbeiten] POSIX-basierte Zeichenklassen
Diese Zeichenklassen sind eine Erweiterung der ECMAScript-Grammatik und entsprechen den Zeichenklassen, die in POSIX-Regulären Ausdrücken gefunden werden.
ClassAtomExClass(nur C++) :
-
[:ClassName:]
Repräsentiert alle Zeichen, die Mitglieder der benannten Zeichenklasse ClassName sind. Der Name ist nur gültig, wenn std::regex_traits::lookup_classname für diesen Namen einen von Null verschiedenen Wert zurückgibt. Wie in std::regex_traits::lookup_classname beschrieben, werden die folgenden Namen garantiert erkannt: alnum, alpha, blank, cntrl, digit, graph, lower, print, punct, space, upper, xdigit, d, s, w. Zusätzliche Namen können von systemseitigen Locales bereitgestellt werden (wie jdigit oder jkanji im Japanischen) oder als benutzerdefinierte Erweiterung implementiert werden.
ClassAtomCollatingElement(nur C++) :
-
[.ClassName.]
Repräsentiert das benannte Kollationselement, das ein einzelnes Zeichen oder eine Zeichenfolge darstellen kann, die unter der eingebundenen Locale als eine Einheit kollationiert wird, z.B. [.tilde.] oder [.ch.] im Tschechischen. Der Name ist nur gültig, wenn std::regex_traits::lookup_collatename keinen leeren String zurückgibt.
Bei Verwendung von std::regex_constants::collate können Kollationselemente immer als Endpunkte eines Bereichs verwendet werden (z.B. [[.dz.]-g] im Ungarischen).
ClassAtomEquivalence(nur C++) :
-
[=ClassName=]
Repräsentiert alle Zeichen, die Mitglieder derselben Äquivalenzklasse wie das benannte Kollationselement sind, d.h. alle Zeichen, deren primärer Kollationsschlüssel derselbe ist wie der für das Kollationselement ClassName. Der Name ist nur gültig, wenn std::regex_traits::lookup_collatename für diesen Namen kein leerer String ist und wenn der von std::regex_traits::transform_primary zurückgegebene Wert für das Ergebnis des Aufrufs von std::regex_traits::lookup_collatename kein leerer String ist.
Ein primärer Sortierschlüssel ist einer, der Groß-/Kleinschreibung, Akzentuierung oder locale-spezifische Anpassungen ignoriert; so gleicht zum Beispiel [[=a=]] eines der folgenden Zeichen ab: a, À, Á, Â, Ã, Ä, Å, A, à, á, â, ã, ä und å.
ClassName(nur C++) :
- ClassNameCharacter
- ClassNameCharacter ClassName
ClassNameCharacter(nur C++) :
- SourceCharacter, aber nicht
. = :
| Dieser Abschnitt ist unvollständig Grund: kein Beispiel |