Modified ECMAScript regular expression grammar
Diese Seite beschreibt die Grammatik regulärer Ausdrücke, die verwendet wird, wenn
std::basic_regex
mit
syntax_option_type
auf
ECMAScript
gesetzt erstellt wird (der Standardwert). Siehe
syntax_option_type
für die anderen unterstützten Grammatiken regulärer Ausdrücke.
Die
ECMAScript
3 reguläre Ausdrucksgrammatik in C++ ist die
ECMA-262 Grammatik
mit unten markierten Modifikationen
(nur C++)
.
Inhaltsverzeichnis |
Übersicht
Die modifizierte reguläre Ausdrucksgrammatik ist größtenteils ECMAScript RegExp-Grammatik mit einer POSIX-artigen Erweiterung für Locales unter ClassAtom . Einige Klarstellungen zu Gleichheitsüberprüfungen und Zahlenparsing wurden vorgenommen. Für viele der Beispiele hier können Sie dieses Äquivalent in Ihrer Browser-Konsole ausprobieren:
function match(s, re) { return s.match(new RegExp(re)); }
Die "normativen Referenzen" im Standard spezifizieren ECMAScript 3. Wir verlinken hier auf die ECMAScript 5.1-Spezifikation, da es sich um eine Version mit nur geringfügigen Änderungen gegenüber ECMAScript 3 handelt und sie auch eine HTML-Version verfügbar hat. Siehe den MDN-Leitfaden zu JavaScript RegExp für einen Überblick über die Dialektfunktionen.
Alternativen
Ein regulärer Ausdrucksmuster ist eine Sequenz von einem oder mehreren
Alternative
n, getrennt durch den Disjunktionsoperator
|
(mit anderen Worten, der Disjunktionsoperator hat die niedrigste Priorität).
Pattern ::
- Disjunktion
Disjunktion ::
- Alternative
-
Alternative
|Disjunktion
Das Muster versucht zunächst, die Disjunction zu überspringen und die linke Alternative gefolgt vom Rest des regulären Ausdrucks (nach der Disjunction) zu matchen.
Wenn es fehlschlägt, versucht es, die linke Alternative zu überspringen und die rechte Disjunktion abzugleichen (gefolgt vom Rest des regulären Ausdrucks).
Wenn die linke Alternative , die rechte Disjunktion und der Rest des regulären Ausdrucks alle Wahlpunkte haben, werden alle Optionen im Rest des Ausdrucks ausprobiert, bevor zur nächsten Option in der linken Alternative übergegangen wird. Wenn die Optionen in der linken Alternative erschöpft sind, wird stattdessen die rechte Disjunktion anstelle der linken Alternative versucht.
Jede erfassende Klammer innerhalb eines übersprungenen Alternative erzeugt 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=[]
Begriffe
Jede Alternative ist entweder leer oder eine Sequenz von Term s (ohne Trennzeichen zwischen den Term s)
Alternative ::
- [leer]
- Alternative Bezeichnung
Leere Alternative stimmt immer überein und verbraucht keine Eingabe.
Aufeinanderfolgende Term e versuchen gleichzeitig aufeinanderfolgende Abschnitte der Eingabe abzugleichen.
Wenn die linke Alternative , der rechte Term und der Rest des regulären Ausdrucks alle Wahlpunkte haben, werden alle Möglichkeiten im Rest des Ausdrucks ausprobiert, bevor zur nächsten Option im rechten Term übergegangen wird, und alle Möglichkeiten im rechten Term werden ausprobiert, bevor zur nächsten Option 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", ""); // leere Regex ist eine einzelne leere Alternative show_matches("abc", "abc|"); // linke Alternative wird zuerst gematcht show_matches("abc", "|abc"); // linke Alternative wird zuerst gematcht, lässt abc ungematcht }
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]
Quantifizierer
- Jeder Term ist entweder eine Assertion (siehe unten), oder ein Atom (siehe unten), oder ein Atom unmittelbar gefolgt von einem Quantifier
Term ::
- Assertion
- Atom
- Atom Quantifier
Jeder
Quantifier
ist entweder ein
greedy
Quantifier (der nur aus einem einzigen
QuantifierPrefix
besteht) oder ein
non-greedy
Quantifier (der aus einem
QuantifierPrefix
gefolgt vom Fragezeichen
?
besteht).
Quantifier ::
- QuantifierPrefix
-
QuantifierPrefix
?
Jedes QuantifierPrefix bestimmt zwei Zahlen: die minimale Anzahl der Wiederholungen und die maximale Anzahl der Wiederholungen, wie folgt:
| QuantifierPrefix | Minimum | Maximum |
|---|---|---|
*
|
null | unendlich |
+
|
eins | unendlich |
?
|
null | eins |
{
DecimalDigits
}
|
Wert von DecimalDigits | Wert von DecimalDigits |
{
DecimalDigits
,
}
|
Wert von DecimalDigits | unendlich |
{
DecimalDigits
,
DecimalDigits
}
|
Wert von DecimalDigits vor dem Komma | Wert von DecimalDigits nach dem Komma |
Die Werte der einzelnen DecimalDigits werden durch Aufruf von std::regex_traits::value (Nur C++) für jede der Ziffern erhalten.
Ein Atom gefolgt von einem Quantifier wird so oft wiederholt, wie durch den Quantifier angegeben. Ein Quantifier kann non-greedy sein, wobei das Atom -Muster so wenige Male wie möglich wiederholt wird, während der Rest des regulären Ausdrucks noch übereinstimmt, oder es kann greedy sein, wobei das Atom -Muster so oft wie möglich wiederholt wird, während der Rest des regulären Ausdrucks noch übereinstimmt.
Das Atom -Muster ist das, was wiederholt wird, nicht die Eingabe, die es abgleicht, sodass verschiedene Wiederholungen des Atom verschiedene Eingabe-Teilzeichenfolgen abgleichen können.
Wenn sowohl das Atom als auch der Rest des regulären Ausdrucks Wahlpunkte haben, wird das Atom zuerst so oft (oder so selten, wenn non-greedy ) wie möglich gematcht. Alle Wahlmöglichkeiten im Rest des regulären Ausdrucks werden ausprobiert, bevor zur nächsten Wahl in der letzten Wiederholung des Atom übergegangen wird. Alle Wahlmöglichkeiten in der letzten (n-ten) Wiederholung des Atom werden ausprobiert, bevor zur nächsten Wahl in der vorletzten (n-1)-ten Wiederholung des Atom übergegangen wird; zu diesem Zeitpunkt kann sich herausstellen, dass mehr oder weniger Wiederholungen des Atom jetzt möglich sind; diese werden ausgeschöpft (wiederum beginnend mit entweder so wenigen oder so vielen wie möglich), bevor zur nächsten Wahl in der (n-1)-ten Wiederholung des Atom übergegangen wird und so weiter.
Die Atom' s-Captures werden jedes Mal gelöscht, wenn es wiederholt wird (siehe das "(z)((a+)?(b+)?(c))*" 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() { // gierige Übereinstimmung, wiederholt [a-z] 4-mal show_matches("abcdefghi", "a[a-z]{2,4}"); // nicht-gierige Übereinstimmung, wiederholt [a-z] 2-mal show_matches("abcdefghi", "a[a-z]{2,4}?"); // Auswahlpunkt-Reihenfolge für Quantifizierer führt zu einer Übereinstimmung // mit zwei Wiederholungen, wobei die erste die Teilzeichenkette "aa" abgleicht, // die zweite die Teilzeichenkette "ba" abgleicht und "ac" nicht abgeglichen wird // ("ba" erscheint in der Erfassungsklausel m[1]) show_matches("aabaac", "(aa|aabaac|ba|b|c)*"); // Auswahlpunkt-Reihenfolge für Quantifizierer ermöglicht dieser Regex // den größten gemeinsamen Teiler zwischen 10 und 15 zu berechnen // (die Antwort ist 5, und sie füllt m[1] mit "aaaaa") show_matches("aaaaaaaaaa,aaaaaaaaaaaaaaa", "^(a+)\\1*,\\1+$"); // die Teilzeichenkette "bbb" erscheint nicht in der Erfassungsklausel m[4] // weil sie gelöscht wird, wenn die zweite Wiederholung des Atoms // (a+)?(b+)?(c) die Teilzeichenkette "ac" abgleicht // HINWEIS: gcc macht hier einen Fehler - es löscht nicht korrekt die // Erfassungsgruppe matches[4] wie von ECMA-262 21.2.2.5.1 gefordert, // und erfasst daher fälschlicherweise "bbb" für diese Gruppe. 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=[]
Assertions
Assertion s entsprechen Bedingungen, nicht Teilzeichenketten der Eingabezeichenkette. Sie verbrauchen niemals Zeichen aus der Eingabe. Jede Assertion ist eine der folgenden
Assertion ::
-
^ -
$ -
\b -
\B -
(?=Disjunktion) -
(?!Disjunktion)
Die Assertion
^
(Anfang der Zeile) stimmt überein
Die Assertion
$
(Ende der Zeile) stimmt überein
In den beiden obigen Assertionen und im Atom
.
unten ist
LineTerminator
einer der folgenden vier Zeichen:
U+000A
(
\n
oder Zeilenvorschub),
U+000D
(
\r
oder Wagenrücklauf),
U+2028
(Zeilentrenner) oder
U+2029
(Absatztrenner)
Die Assertion
\b
(Wortgrenze) trifft zu
Die Assertion
\B
(negative Wortgrenze) matcht alles AUSSER dem Folgenden
Die Assertion
(
?
=
Disjunction
)
(Null-Breiten-Positive-Lookahead) trifft zu, wenn
Disjunction
an der aktuellen Position auf die Eingabe passen würde
Die Assertion
(
?
!
Disjunction
)
(Zero-Width Negative Lookahead) trifft zu, wenn
Disjunction
NICHT an der aktuellen Position auf die Eingabe passen würde.
Für beide Lookahead-Assertions wird beim Abgleichen der Disjunction die Position nicht vorangetrieben, bevor der Rest des regulären Ausdrucks abgeglichen wird. Außerdem wird, wenn die Disjunction auf mehrere Arten an der aktuellen Position abgeglichen werden kann, nur die erste Möglichkeit versucht.
ECMAScript verbietet das Zurückverfolgen in Lookahead-Disjunktionen, was das Verhalten von Rückverweisen in einen positiven Lookahead vom Rest des regulären Ausdrucks beeinflusst (siehe Beispiel unten). Rückverweise in den negativen Lookahead vom Rest des regulären Ausdrucks sind immer undefiniert (da die Lookahead-Disjunktion fehlschlagen muss, um fortzufahren).
Hinweis: Lookahead-Assertions können verwendet werden, um ein logisches UND 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() { // findet das a am Ende der Eingabe show_matches("aaa", "a$"); // findet das o am Ende des ersten Wortes show_matches("moo goo gai pan", "o\\b"); // die Lookahead-Expression findet die leere Zeichenkette direkt nach dem ersten b // dies füllt m[1] mit "aaa", obwohl m[0] leer ist show_matches("baaabac", "(?=(a+))"); // weil Backtracking in Lookaheads verboten ist, // findet dies aba statt aaaba show_matches("baaabac", "(?=(a+))a*b\\1"); // logisches UND via Lookahead: dieses Passwort stimmt überein, WENN es // mindestens einen Kleinbuchstaben // UND mindestens einen Großbuchstaben // UND mindestens ein Satzzeichen enthält // UND mindestens 6 Zeichen lang ist 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=[]
Atome
Ein Atom kann eines der folgenden sein:
Atom ::
- PatternCharacter
-
. -
\AtomEscape - CharacterClass
-
(Disjunction) -
(?:Disjunction)
wo AtomEscape ::
- DezimalEscape
- ZeichenEscape
- ZeichenklassenEscape
Verschiedene Arten von Atomen werden unterschiedlich ausgewertet.
Teilausdrücke
Das
Atom
(
Disjunktion
)
ist ein markierter Teilausdruck: Es führt die
Disjunktion
aus und speichert die Kopie der Eingabe-Teilzeichenkette, die von der
Disjunktion
konsumiert wurde, im Submatch-Array an dem Index, der der Anzahl der bisher im gesamten regulären Ausdruck angetroffenen linken öffnenden Klammern
(
markierter Teilausdrücke entspricht.
Neben der Rückgabe in
std::match_results
sind die erfassten Submatches als Backreferences (
\1
,
\2
, ...) zugänglich und können in regulären Ausdrücken referenziert werden. Beachten Sie, dass
std::regex_replace
$
anstelle von
\
für Backreferences verwendet (
$1
,
$2
, ...), analog zu
String.prototype.replace
(ECMA-262, Abschnitt 15.5.4.11).
Das
Atom
(
?
:
Disjunction
)
(nicht-markierender Teilausdruck) wertet einfach die
Disjunction
aus und speichert ihre Ergebnisse nicht im Submatch. Dies ist eine rein lexikalische Gruppierung.
|
Dieser Abschnitt ist unvollständig
Grund: Kein Beispiel |
Backreferenzen
DecimalEscape ::
- DecimalIntegerLiteral [ lookahead ∉ DecimalDigit ]
Wenn
\
von einer Dezimalzahl
N
gefolgt wird, deren erste Ziffer nicht
0
ist, dann wird die Escape-Sequenz als
Backreference
betrachtet. Der Wert
N
wird durch Aufruf von
std::regex_traits::value
(nur C++)
auf jede der Ziffern erhalten und durch Kombination ihrer Ergebnisse unter Verwendung von Basis-10-Arithmetik. Es ist ein Fehler, wenn
N
größer ist als die Gesamtanzahl der linken erfassenden Klammern im gesamten regulären Ausdruck.
Wenn ein Backreference
\N
als ein
Atom
erscheint, matcht es dieselbe Teilzeichenkette, die aktuell im N-ten Element des Submatch-Arrays gespeichert ist.
Die dezimale Escape-Sequenz
\0
ist KEINE Rückreferenz: Es handelt sich um eine Zeichen-Escape-Sequenz, die das
NUL
-Zeichen repräsentiert. Ihr darf keine dezimale Ziffer folgen.
Wie oben erwähnt, beachten Sie, dass
std::regex_replace
für Backreferences (
$1
,
$2
, ...)
$
anstelle von
\
verwendet.
|
Dieser Abschnitt ist unvollständig
Grund: Kein Beispiel |
Einzelzeichen-Übereinstimmungen
Das
Atom
.
erkennt und konsumiert ein beliebiges Zeichen aus der Eingabezeichenkette mit Ausnahme von
LineTerminator
(
U+000D
,
U+000A
,
U+2029
, oder
U+2028
)
Das
Atom
PatternCharacter
, wobei
PatternCharacter
ein beliebiges
SourceCharacter
AUSSER den Zeichen
^ $ \ . * + ? ( ) [ ] { } |
ist, gleicht ein Zeichen aus der Eingabe ab und konsumiert es, wenn es diesem
PatternCharacter
entspricht.
Die Gleichheit für dieses und alle anderen Einzelzeichen-Übereinstimmungen ist wie folgt definiert:
Jedes
Atom
, das aus dem Escape-Zeichen
\
gefolgt von
CharacterEscape
besteht, sowie das spezielle DecimalEscape
\0
, findet eine Übereinstimmung und verbraucht ein Zeichen aus der Eingabe, wenn es gleich dem durch die
CharacterEscape
dargestellten Zeichen ist. 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 | Seitenvorschub |
n
|
U+000A | Zeilenvorschub |
r
|
U+000D | Wagenrücklauf |
t
|
U+0009 | horizontaler Tabulator |
v
|
U+000B | vertikaler Tabulator |
ControlLetter
ist ein beliebiger Klein- oder Großbuchstabe im ASCII-Zeichensatz, und diese Steuerzeichen-Escape-Sequenz entspricht dem Zeichen, dessen Codeeinheit gleich dem Rest der Division des Werts der Codeeinheit von
ControlLetter
durch
32
ist. Zum Beispiel entsprechen sowohl
\cD
als auch
\cd
der Codeeinheit
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
HexDigit
s (wobei
HexDigit
eines von
0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
ist). 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
HexDigit
s. Diese Zeichen-Escape-Sequenz entspricht dem Zeichen, dessen Code-Einheit dem numerischen Wert dieser vierstelligen Hexadezimalzahl entspricht. Wenn der Wert nicht in den
std::basic_regex
-Typ
CharT
passt, wird
std::regex_error
geworfen
(nur C++)
.
IdentityEscape kann ein beliebiges nicht-alphanumerisches Zeichen sein: zum Beispiel ein weiterer Backslash. Es entspricht dem Zeichen unverändert.
#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() { // Die meisten Escape-Sequenzen ähneln C++, außer bei Metazeichen. Sie müssen // entweder doppelt escapen oder Raw-Strings für die Schrägstriche verwenden. show_matches(L"C++\\", LR"(C\+\+\\)"); // Escape-Sequenzen und NUL. std::wstring s(L"ab\xff\0cd", 5); show_matches(s, L"(\\0|\\u00ff)"); // Für Nicht-BMP-Unicode ist keine Übereinstimmung definiert, da ECMAScript UTF-16 // Atome verwendet. Ob dieses Emoji-Banane übereinstimmt, kann plattformabhängig sein: // Dies müssen Wide-Strings sein! 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
Zeichenklassen
Ein Atom kann eine Zeichenklasse repräsentieren, das heißt, es wird ein Zeichen finden und verarbeiten, wenn es zu einer der vordefinierten Gruppen von Zeichen gehört.
Eine Zeichenklasse kann durch eine Zeichenklassen-Escape-Sequenz eingeführt werden:
Atom ::
-
\Zeichenklassen-Escape
oder direkt
Atom ::
- Zeichenklasse
Die Zeichenklassen-Escapes sind Kurzformen für einige der gebräuchlichen Zeichenklassen, wie folgt:
| CharacterClassEscape | ClassName expression (C++ only) | Bedeutung |
|---|---|---|
d
|
[[:digit:]]
|
Ziffern |
D
|
[^[:digit:]]
|
Nicht-Ziffern |
s
|
[[:space:]]
|
Leerzeichenzeichen |
S
|
[^[:space:]]
|
Nicht-Leerzeichenzeichen |
w
|
[_[:alnum:]]
|
Alphanumerische Zeichen und das Zeichen
_
|
W
|
[^_[:alnum:]]
|
Zeichen außer alphanumerischen oder
_
|
Eine
CharacterClass
ist eine in Klammern eingeschlossene Sequenz von
ClassRanges
, die optional mit dem Negationsoperator
^
beginnt. Wenn sie mit
^
beginnt, passt dieses
Atom
auf jedes Zeichen, das NICHT in der Menge der Zeichen enthalten ist, die durch die Vereinigung aller
ClassRanges
repräsentiert wird. Andernfalls passt dieses
Atom
auf jedes Zeichen, das in der Menge der Zeichen enthalten ist, die durch die Vereinigung aller
ClassRanges
repräsentiert wird.
CharacterClass ::
-
[[lookahead ∉ {^}] ClassRanges] -
[^ClassRanges]
ClassRanges ::
- [leer]
- NonemptyClassRanges
NonemptyClassRanges ::
- ClassAtom
- ClassAtom NonemptyClassRangesNoDash
- ClassAtom - ClassAtom ClassRanges
Wenn ein nicht-leerer Klassenbereich die Form
ClassAtom
-
ClassAtom
hat, entspricht er jedem Zeichen aus einem Bereich, der wie folgt definiert ist:
(Nur C++)
Das erste
ClassAtom
muss auf ein einzelnes Sortierelement
c1
passen und das zweite
ClassAtom
muss auf ein einzelnes Sortierelement
c2
passen. Um zu prüfen, ob das Eingabezeichen
c
von dieser Range erfasst wird, werden folgende Schritte unternommen:
c
wird gematcht, 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
wird gematcht, wenn
transformed c1 <= transformed c && transformed c <= transformed c2
Das Zeichen
-
wird wörtlich behandelt, wenn es
- das erste oder letzte Zeichen von ClassRanges
- das erste oder letzte ClassAtom einer durch Bindestrich getrennten Bereichsangabe
- unmittelbar nach einer durch Bindestrich getrennten Bereichsangabe folgt
- mit einem Backslash als CharacterEscape maskiert
NonemptyClassRangesNoDash ::
- ClassAtom
- ClassAtomNoDash NonemptyClassRangesNoDash
- ClassAtomNoDash - ClassAtom ClassRanges
ClassAtom ::
-
- - ClassAtomNoDash
- ClassAtomExClass (nur C++)
- ClassAtomCollatingElement (nur C++)
- ClassAtomEquivalence (nur C++)
ClassAtomNoDash ::
-
SourceCharacter
aber nicht eines von
\ oder ] oder - -
\ClassEscape
Jedes ClassAtomNoDash repräsentiert ein einzelnes Zeichen – entweder SourceCharacter unverändert oder wie folgt escaped:
ClassEscape ::
- DezimalEscape
-
b - ZeichenEscape
-
ZeichenklassenEscape
Das spezielle
ClassEscape
\b
erzeugt einen Zeichensatz, der der Codeeinheit U+0008 (Rücktaste) entspricht. Außerhalb einer
CharacterClass
handelt es sich um die
Assertion
für Wortgrenzen.
Die Verwendung von
\B
und die Verwendung jeglicher Rückreferenz (
DecimalEscape
außer Null) innerhalb einer
CharacterClass
ist ein Fehler.
Die Zeichen
-
und
]
müssen in einigen Situationen escaped werden, um als Atome behandelt zu werden. Andere Zeichen mit spezieller Bedeutung außerhalb von
CharacterClass
, wie
*
oder
?
, müssen nicht escaped werden.
|
Dieser Abschnitt ist unvollständig
Grund: Kein Beispiel |
POSIX-basierte Zeichenklassen
Diese Zeichenklassen sind eine Erweiterung der ECMAScript-Grammatik und entsprechen den Zeichenklassen, die in den POSIX-Regulären Ausdrücken zu finden sind.
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 Wert ungleich Null zurückgibt. Wie in
std::regex_traits::lookup_classname
beschrieben, sind die folgenden Namen garantiert erkennbar:
alnum, alpha, blank, cntrl, digit, graph, lower, print, punct, space, upper, xdigit, d, s, w
. Zusätzliche Namen können durch systemseitig bereitgestellte Locales (wie
jdigit
oder
jkanji
im Japanischen) bereitgestellt oder als benutzerdefinierte Erweiterung implementiert werden.
ClassAtomCollatingElement (Nur C++) ::
-
[.ClassName.]
Repräsentiert das benannte Kollationselement, das entweder ein einzelnes Zeichen oder eine Zeichenfolge darstellen kann, die unter der eingestellten Locale als eine einzelne Einheit kollationiert, wie z.B.
[.tilde.]
oder
[.ch.]
im Tschechischen. Der Name ist nur gültig, wenn
std::regex_traits::lookup_collatename
kein leerer String ist.
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 Kollatierungselement sind, das heißt alle Zeichen, deren primärer Kollationsschlüssel derselbe ist wie der für das Kollatierungselement ClassName . Der Name ist nur gültig, wenn std::regex_traits::lookup_collatename für diesen Namen keine leere Zeichenkette zurückgibt und wenn der von std::regex_traits::transform_primary für das Ergebnis des Aufrufs von std::regex_traits::lookup_collatename zurückgegebene Wert keine leere Zeichenkette ist.
Ein primärer Sortierschlüssel ist einer, der Groß-/Kleinschreibung, Akzentuierung oder localespezifische Anpassungen ignoriert; so entspricht beispielsweise
[[=a=]]
jedem der Zeichen:
a, À, Á, Â, Ã, Ä, Å, A, à, á, â, ã, ä and å.
ClassName (nur C++) ::
- KlassennameZeichen
- KlassennameZeichen ClassName
ClassNameCharacter (nur C++) ::
-
SourceCharacter
aber nicht eines von
. = :
|
Dieser Abschnitt ist unvollständig
Grund: Kein Beispiel |