Modified ECMAScript regular expression grammar
На этой странице описывается грамматика регулярных выражений, которая используется при
std::basic_regex
с установленным
syntax_option_type
в значение
ECMAScript
(по умолчанию). Смотрите
syntax_option_type
для других поддерживаемых грамматик регулярных выражений.
Грамматика регулярных выражений
ECMAScript
3 в C++ основана на
грамматике ECMA-262
с модификациями, отмеченными
(только для C++)
ниже.
Содержание |
Обзор
Модифицированная грамматика регулярных выражений в основном представляет собой грамматику ECMAScript RegExp с POSIX-подобным расширением для локалей в ClassAtom . Внесены некоторые уточнения относительно проверок равенства и разбора чисел. Для многих примеров здесь вы можете попробовать эквивалент в консоли вашего браузера:
function match(s, re) { return s.match(new RegExp(re)); }
"Нормативные ссылки" в стандарте указывают на ECMAScript 3. Мы ссылаемся на спецификацию ECMAScript 5.1 здесь, поскольку это версия с незначительными изменениями по сравнению с ECMAScript 3, и она также имеет HTML-версию. Смотрите Руководство MDN по JavaScript RegExp для обзора особенностей диалекта.
Альтернативы
Шаблон регулярного выражения представляет собой последовательность из одного или нескольких
Alternative
, разделенных оператором дизъюнкции
|
(другими словами, оператор дизъюнкции имеет самый низкий приоритет).
Pattern ::
- Дизъюнкция
Дизъюнкция ::
- Альтернатива
-
Альтернатива
|Дизъюнкция
Паттерн сначала пытается пропустить Disjunction и сопоставить левую Alternative с последующей частью регулярного выражения (после Disjunction).
Если это не удается, он пытается пропустить левый Alternative и сопоставить правый Disjunction (с последующей частью регулярного выражения).
Если левая Альтернатива , правая Дизъюнкция и остаток регулярного выражения имеют точки выбора, все варианты в остатке выражения проверяются перед переходом к следующему варианту в левой Альтернативе . Если варианты в левой Альтернативе исчерпаны, правая Дизъюнкция проверяется вместо левой Альтернативы .
Любые захватывающие скобки внутри пропущенной Alternative создают пустые подсовпадения.
#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"); // сначала найдено левое альтернативное выражение // Сопоставление ввода с левым альтернативным выражением (a), за которым // следует остаток регулярного выражения (c|bc), завершается успешно, что приводит // к m[1]="a" и m[4]="bc". // Пропущенные альтернативные выражения (ab) и (c) оставляют свои подсовпадения // m[3] и m[5] пустыми. show_matches("abc", "((a)|(ab))((c)|(bc))"); }
Вывод:
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=[]
Термины
Каждый Alternative либо пуст, либо является последовательностью Term ов (без разделителей между Term ами)
Альтернативный ::
- [пусто]
- Альтернативный Термин
Пустой Альтернативный всегда соответствует и не потребляет никакой ввод.
Последовательные Термы пытаются одновременно сопоставить последовательные части входных данных.
Если левая Альтернатива , правый Терм и остаток регулярного выражения все имеют точки выбора, все варианты в остатке выражения проверяются перед переходом к следующему варианту в правом Терме , и все варианты в правом Терме проверяются перед переходом к следующему варианту в левой Альтернативе .
#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", ""); // пустое регулярное выражение представляет собой единственную пустую альтернативу show_matches("abc", "abc|"); // сначала сопоставляется левая альтернатива show_matches("abc", "|abc"); // сначала сопоставляется левая альтернатива, оставляя abc несопоставленным }
Вывод:
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]
Квантификаторы
- Каждый Терм является либо Утверждением (см. ниже), либо Атомом (см. ниже), либо Атомом , за которым непосредственно следует Квантор
Термин ::
- Утверждение
- Атом
- Атом Квантор
Каждый
Quantifier
является либо
greedy
квантификатором (который состоит только из одного
QuantifierPrefix
), либо
non-greedy
квантификатором (который состоит из одного
QuantifierPrefix
, за которым следует знак вопроса
?
).
Квантификатор ::
- КванторныйПрефикс
-
КванторныйПрефикс
?
Каждый QuantifierPrefix определяет два числа: минимальное количество повторений и максимальное количество повторений, следующим образом:
| QuantifierPrefix | Минимум | Максимум |
|---|---|---|
*
|
ноль | бесконечность |
+
|
один | бесконечность |
?
|
ноль | один |
{
DecimalDigits
}
|
значение DecimalDigits | значение DecimalDigits |
{
DecimalDigits
,
}
|
значение DecimalDigits | бесконечность |
{
DecimalDigits
,
DecimalDigits
}
|
значение DecimalDigits перед запятой | значение DecimalDigits после запятой |
Значения отдельных DecimalDigits получаются путем вызова std::regex_traits::value (только для C++) для каждой из цифр.
Атом, за которым следует Квантификатор, повторяется количество раз, указанное Квантификатором. Квантификатор может быть нежадным, в этом случае шаблон Атома повторяется минимально возможное количество раз, при котором всё ещё соответствует остатку регулярного выражения, или он может быть жадным, в этом случае шаблон Атома повторяется максимально возможное количество раз, при котором всё ещё соответствует остатку регулярного выражения.
Шаблон Atom повторяется, а не входные данные, которые он сопоставляет, поэтому различные повторения Atom могут соответствовать разным подстрокам входных данных.
Если у Atom и остальной части регулярного выражения есть точки выбора, сначала Atom сопоставляется столько раз (или так мало раз, если используется non-greedy режим), сколько возможно. Все варианты в остальной части регулярного выражения проверяются перед переходом к следующему варианту в последнем повторении Atom . Все варианты в последнем (n-м) повторении Atom проверяются перед переходом к следующему варианту в предпоследнем (n–1)-м повторении Atom ; в этот момент может оказаться, что теперь возможно большее или меньшее количество повторений Atom ; они исчерпываются (снова, начиная с минимального или максимального возможного количества) перед переходом к следующему варианту в (n-1)-м повторении Atom и так далее.
Захваты Atom' a очищаются каждый раз, когда он повторяется (см. пример "(z)((a+)?(b+)?(c))*" ниже)
#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() { // жадное совпадение, повторяет [a-z] 4 раза show_matches("abcdefghi", "a[a-z]{2,4}"); // нежадное совпадение, повторяет [a-z] 2 раза show_matches("abcdefghi", "a[a-z]{2,4}?"); // Порядок точек выбора для квантификаторов приводит к совпадению // с двумя повторениями, первое соответствует подстроке "aa", // второе соответствует подстроке "ba", оставляя "ac" несовпавшим // ("ba" появляется в группе захвата m[1]) show_matches("aabaac", "(aa|aabaac|ba|b|c)*"); // Порядок точек выбора для квантификаторов позволяет этому регулярному выражению // вычислить наибольший общий делитель между 10 и 15 // (ответ 5, и оно заполняет m[1] значением "aaaaa") show_matches("aaaaaaaaaa,aaaaaaaaaaaaaaa", "^(a+)\\1*,\\1+$"); // подстрока "bbb" не появляется в группе захвата m[4] // потому что она очищается, когда второе повторение атома // (a+)?(b+)?(c) соответствует подстроке "ac" // ПРИМЕЧАНИЕ: gcc ошибается здесь - он не очищает правильно // группу захвата matches[4] как требуется по ECMA-262 21.2.2.5.1, // и поэтому неправильно захватывает "bbb" для этой группы. show_matches("zaacbbbcac", "(z)((a+)?(b+)?(c))*"); }
Вывод:
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=[]
Утверждения
Утверждение соответствует условиям, а не подстрокам входной строки. Они никогда не потребляют никакие символы из входных данных. Каждое Утверждение является одним из следующих
Утверждение ::
-
^ -
$ -
\b -
\B -
(?=Дизъюнкция) -
(?!Дизъюнкция)
Утверждение
^
(начало строки) соответствует
Утверждение
$
(конец строки) соответствует
В двух приведенных выше утверждениях и в атоме
.
ниже,
LineTerminator
является одним из следующих четырех символов:
U+000A
(
\n
или перевод строки),
U+000D
(
\r
или возврат каретки),
U+2028
(разделитель строк), или
U+2029
(разделитель параграфов)
Утверждение
\b
(граница слова) соответствует
Утверждение
\B
(отрицательная граница слова) соответствует всему, КРОМЕ следующего
Утверждение
(
?
=
Disjunction
)
(позитивный просмотр вперед нулевой ширины) совпадает, если
Disjunction
соответствует входным данным в текущей позиции
Утверждение
(
?
!
Disjunction
)
(отрицающий просмотр вперед нулевой ширины) совпадает, если
Disjunction
НЕ совпадает с входными данными в текущей позиции.
Для обоих утверждений предварительного просмотра, при сопоставлении Disjunction , позиция не продвигается перед сопоставлением оставшейся части регулярного выражения. Кроме того, если Disjunction может быть сопоставлен в текущей позиции несколькими способами, пробуется только первый из них.
ECMAScript запрещает возврат в опережающие проверки (lookahead Disjunctions), что влияет на поведение обратных ссылок (backreferences) в положительной опережающей проверке (positive lookahead) из оставшейся части регулярного выражения (см. пример ниже). Обратные ссылки в отрицательной опережающей проверке (negative lookahead) из остальной части регулярного выражения всегда неопределены (поскольку опережающая проверка должна завершиться неудачей для продолжения).
Примечание: Опережающие проверки могут использоваться для создания логического И между несколькими регулярными выражениями (см. пример ниже).
#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() { // соответствует 'a' в конце входной строки show_matches("aaa", "a$"); // соответствует 'o' в конце первого слова show_matches("moo goo gai pan", "o\\b"); // опережающая проверка соответствует пустой строке сразу после первой 'b' // это заполняет m[1] значением "aaa", хотя m[0] пуст show_matches("baaabac", "(?=(a+))"); // поскольку возврат в опережающие проверки запрещен, // это соответствует 'aba', а не 'aaaba' show_matches("baaabac", "(?=(a+))a*b\\1"); // логическое И через опережающую проверку: этот пароль соответствует, ЕСЛИ он содержит // как минимум одну строчную букву // И как минимум одну заглавную букву // И как минимум один знак пунктуации // И имеет длину не менее 6 символов show_matches("abcdef", "(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}"); show_matches("aB,def", "(?=.*[[:lower:]])(?=.*[[:upper:]])(?=.*[[:punct:]]).{6,}"); }
Вывод:
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=[]
Атомы
Атом может быть одним из следующих:
Atom ::
- СимволШаблона
-
. -
\ЭкранированиеАтома - КлассСимволов
-
(Дизъюнкция) -
(?:Дизъюнкция)
где AtomEscape ::
- DecimalEscape
- CharacterEscape
- CharacterClassEscape
Различные виды атомов оцениваются по-разному.
Подвыражения
Atom
(
Disjunction
)
является помеченным подвыражением: оно выполняет
Disjunction
и сохраняет копию входной подстроки, которая была обработана
Disjunction
в массиве submatch по индексу, соответствующему количеству раз, когда левая открывающая скобка
(
помеченных подвыражений была встречена во всем регулярном выражении на данный момент.
Помимо возвращения в
std::match_results
, захваченные подсовпадения доступны как обратные ссылки (
\1
,
\2
, ...) и могут использоваться в регулярных выражениях. Обратите внимание, что
std::regex_replace
использует
$
вместо
\
для обратных ссылок (
$1
,
$2
, ...) аналогично
String.prototype.replace
(ECMA-262, часть 15.5.4.11).
Atom
(
?
:
Disjunction
)
(несохраняющая подвыражение) просто вычисляет
Disjunction
и не сохраняет его результаты в submatch. Это чисто лексическая группировка.
|
Этот раздел не завершён
Причина: отсутствует пример |
Обратные ссылки
DecimalEscape ::
- DecimalIntegerLiteral [ lookahead ∉ DecimalDigit ]
Если
\
следует десятичное число
N
, первая цифра которого не равна
0
, то такая escape-последовательность считается
обратной ссылкой
. Значение
N
получается вызовом
std::regex_traits::value
(только для C++)
для каждой цифры с последующим объединением результатов с использованием десятичной арифметики. Ошибкой является случай, когда
N
превышает общее количество левых захватывающих скобок во всём регулярном выражении.
Когда обратная ссылка
\N
выступает как
Atom
, она соответствует той же подстроке, которая в данный момент хранится в N-м элементе массива подсовпадений.
Десятичная escape-последовательность
\0
НЕ является обратной ссылкой: это символьная escape-последовательность, которая представляет
NUL
символ. После неё не может следовать десятичная цифра.
Как упомянуто выше, обратите внимание, что
std::regex_replace
использует
$
вместо
\
для обратных ссылок (
$1
,
$2
, ...).
|
Этот раздел не завершён
Причина: отсутствует пример |
Совпадения одиночных символов
Atom
.
сопоставляется и потребляет любой один символ из входной строки, за исключением
LineTerminator
(
U+000D
,
U+000A
,
U+2029
, или
U+2028
)
Атом
PatternCharacter
, где
PatternCharacter
— это любой
SourceCharacter
, ЗА ИСКЛЮЧЕНИЕМ символов
^ $ \ . * + ? ( ) [ ] { } |
, сопоставляется и потребляет один символ из входных данных, если он равен этому
PatternCharacter
.
Равенство для этого и всех остальных одиночных символов определяется следующим образом:
Каждый
Atom
, состоящий из escape-символа
\
, за которым следует
CharacterEscape
, а также специальный DecimalEscape
\0
, сопоставляется и потребляет один символ из входных данных, если он равен символу, представленному
CharacterEscape
. Распознаются следующие escape-последовательности символов:
CharacterEscape ::
- ControlEscape
-
cControlLetter - HexEscapeSequence
- UnicodeEscapeSequence
- IdentityEscape
Здесь
ControlEscape
является одним из следующих пяти символов:
f n r t v
| ControlEscape | Code Unit | Name |
|---|---|---|
f
|
U+000C | перевод формата |
n
|
U+000A | новая строка |
r
|
U+000D | возврат каретки |
t
|
U+0009 | горизонтальная табуляция |
v
|
U+000B | вертикальная табуляция |
ControlLetter
— это любая строчная или заглавная буква ASCII, и эта управляющая последовательность соответствует символу, кодовая единица которого равна остатку от деления значения кодовой единицы
ControlLetter
на
32
. Например,
\cD
и
\cd
соответствуют кодовой единице
U+0004
(EOT), потому что 'D' — это
U+0044
и
0x44
%
32
==
4
, а 'd' — это
U+0064
и
0x64
%
32
==
4
.
HexEscapeSequence
— это символ
x
, за которым следуют ровно две
HexDigit
(где
HexDigit
— это один из символов
0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
). Эта escape-последовательность соответствует символу, кодовая единица которого равна числовому значению двухзначного шестнадцатеричного числа.
UnicodeEscapeSequence
— это символ
u
, за которым следует ровно четыре
HexDigit
. Эта escape-последовательность соответствует символу, кодовая единица которого равна числовому значению этого четырёхзначного шестнадцатеричного числа. Если значение не помещается в
std::basic_regex
's
CharT
,
выбрасывается
std::regex_error
(только для C++)
.
IdentityEscape может быть любым не-буквенно-цифровым символом: например, другой обратный слеш. Он сопоставляет символ как есть.
#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() { // Большинство экранирований аналогичны C++, за исключением метасимволов. Вам придется // удваивать экранирование или использовать сырые строки для слешей. show_matches(L"C++\\", LR"(C\+\+\\)"); // Escape-последовательности и NUL. std::wstring s(L"ab\xff\0cd", 5); show_matches(s, L"(\\0|\\u00ff)"); // Сопоставление для не-BMP Unicode не определено, потому что ECMAScript использует UTF-16 // атомы. Может ли этот эмодзи банан совпасть, может зависеть от платформы: // Это должны быть широкие строки! show_matches(L"\U0001f34c", L"[\\u0000-\\ufffe]+"); }
Возможный вывод:
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
Классы символов
Атом может представлять класс символов, то есть он будет соответствовать и потреблять один символ, если он принадлежит к одной из предопределенных групп символов.
Класс символов может быть введён через escape-последовательность класса символов:
Atom ::
-
\ЭкранированиеКлассаСимволов
или напрямую
Atom ::
- КлассСимволов
Символьные классы с escape-последовательностями являются сокращениями для некоторых распространённых символьных классов, как показано далее:
| CharacterClassEscape | ClassName expression (только C++) | Значение |
|---|---|---|
d
|
[[:digit:]]
|
цифры |
D
|
[^[:digit:]]
|
не-цифры |
s
|
[[:space:]]
|
пробельные символы |
S
|
[^[:space:]]
|
не-пробельные символы |
w
|
[_[:alnum:]]
|
буквенно-цифровые символы и символ
_
|
W
|
[^_[:alnum:]]
|
символы, отличные от буквенно-цифровых или
_
|
CharacterClass
представляет собой заключенную в скобки последовательность
ClassRanges
, которая может начинаться с оператора отрицания
^
. Если она начинается с
^
, данный
Atom
соответствует любому символу, который НЕ входит в набор символов, представленный объединением всех
ClassRanges
. В противном случае данный
Atom
соответствует любому символу, который входит в набор символов, представленный объединением всех
ClassRanges
.
CharacterClass ::
-
[[lookahead ∉ {^}] ClassRanges] -
[^ClassRanges]
ClassRanges ::
- [пустой]
- NonemptyClassRanges
NonemptyClassRanges ::
- ClassAtom
- ClassAtom NonemptyClassRangesNoDash
- ClassAtom - ClassAtom ClassRanges
Если непустой класс символов имеет форму
ClassAtom
-
ClassAtom
, он соответствует любому символу из диапазона, определённого следующим образом:
(только C++)
Первый
ClassAtom
должен соответствовать одному элементу сортировки
c1
, а второй
ClassAtom
должен соответствовать одному элементу сортировки
c2
. Чтобы проверить, соответствует ли входной символ
c
данному диапазону, выполняются следующие шаги:
c
сопоставляется, если
c1 <= c && c <= c2
c
,
c1
, и
c2
) передаются в
std::regex_traits::translate_nocase
c
,
c1
, и
c2
) передаются в
std::regex_traits::translate
c
совпадает, если
transformed c1 <= transformed c && transformed c <= transformed c2
Символ
-
обрабатывается буквально, если он
- первый или последний символ ClassRanges
- начальный или конечный ClassAtom в спецификации диапазона через дефис
- непосредственно следует за спецификацией диапазона через дефис
- экранируется обратной косой чертой как CharacterEscape
NonemptyClassRangesNoDash ::
- ClassAtom
- ClassAtomNoDash NonemptyClassRangesNoDash
- ClassAtomNoDash - ClassAtom ClassRanges
ClassAtom ::
-
- - ClassAtomNoDash
- ClassAtomExClass (только C++)
- ClassAtomCollatingElement (только C++)
- ClassAtomEquivalence (только C++)
ClassAtomNoDash ::
-
SourceCharacter
но не один из
\ или ] или - -
\ClassEscape
Каждый ClassAtomNoDash представляет отдельный символ -- либо SourceCharacter в исходном виде, либо экранированный следующим образом:
ClassEscape ::
- DecimalEscape
-
b - CharacterEscape
- CharacterClassEscape
Специальная
ClassEscape
\b
создает набор символов, соответствующий кодовой единице U+0008 (backspace). За пределами
CharacterClass
это
Assertion
границы слова.
Использование
\B
и использование любой обратной ссылки (
DecimalEscape
отличной от нуля) внутри
CharacterClass
является ошибкой.
Символы
-
и
]
в некоторых ситуациях могут требовать экранирования, чтобы рассматриваться как атомы. Другие символы, имеющие специальное значение вне
CharacterClass
, такие как
*
или
?
, не требуют экранирования.
|
Этот раздел не завершён
Причина: отсутствует пример |
POSIX-классы символов
Эти классы символов являются расширением грамматики ECMAScript и эквивалентны классам символов, встречающимся в регулярных выражениях POSIX.
ClassAtomExClass (только C++) ::
-
[:ClassName:]
Представляет все символы, которые являются членами именованного класса символов
ClassName
. Имя является действительным только если
std::regex_traits::lookup_classname
возвращает ненулевое значение для этого имени. Как описано в
std::regex_traits::lookup_classname
, следующие имена гарантированно распознаются:
alnum, alpha, blank, cntrl, digit, graph, lower, print, punct, space, upper, xdigit, d, s, w
. Дополнительные имена могут предоставляться системными локалями (такие как
jdigit
или
jkanji
в японском языке) или реализованы как пользовательское расширение.
ClassAtomCollatingElement (только C++) ::
-
[.ClassName.]
Представляет именованный элемент сортировки, который может обозначать отдельный символ или последовательность символов, сортируемых как единое целое в текущей локали, например
[.tilde.]
или
[.ch.]
в чешском языке. Имя является действительным только если
std::regex_traits::lookup_collatename
не возвращает пустую строку.
При использовании
std::regex_constants::collate
, элементы сортировки всегда могут использоваться как конечные точки диапазона (например,
[[.dz.]-g]
в венгерском языке).
ClassAtomEquivalence (только C++) ::
-
[=ClassName=]
Представляет все символы, принадлежащие тому же классу эквивалентности, что и именованный элемент сортировки, то есть все символы, чей первичный ключ сортировки совпадает с ключом для элемента сортировки ClassName . Имя действительно только если std::regex_traits::lookup_collatename для этого имени возвращает непустую строку и если значение, возвращаемое std::regex_traits::transform_primary для результата вызова std::regex_traits::lookup_collatename , не является пустой строкой.
Первичный ключ сортировки — это тот, который игнорирует регистр, акценты или локализованные особенности; например,
[[=a=]]
соответствует любым из символов:
a, À, Á, Â, Ã, Ä, Å, A, à, á, â, ã, ä and å.
ClassName (только C++) ::
- ClassNameCharacter
- ClassNameCharacter ClassName
ClassNameCharacter (только C++) ::
-
SourceCharacter
но не один из
. = :
|
Этот раздел не завершён
Причина: отсутствует пример |