Шрифт:
Интервал:
Закладка:
// совпадение
if (1<matches.size() && matches[1].matched)
cout << "t: " << matches[1] << 'n'; // частичное
// совпадение
}
}
Строго говоря, мы не обязаны проверять выражение 1<matches.size(), поскольку уже рассмотрели шаблон, но к этому нас подталкивает легкая паранойя (поскольку мы экспериментируем с разными шаблонами, хранящимися в объекте pat, и не все они содержат только один частичный шаблон). Мы можем проверить, обнаружен ли частичный шаблон, просматривая его член matched, в данном случае matches[1].matched. Нас интересует следующая ситуация: если значение matches[i].matched равно false, то частичные шаблоны matches[i], у которых нет соответствия, выводятся как пустые строки. Аналогично, если частичный шаблон не существует, например matches[17] для приведенного выше шаблона, то он рассматривается как шаблон, у которого нет соответствия.
Мы применили нашу программу к файлу, содержащему следующие строки:
address TX77845
ffff tx 77843 asasasaa
ggg TX3456–23456
howdy
zzz TX23456–3456sss ggg TX33456–1234
cvzcv TX77845–1234 sdsas
xxxTx77845xxx
TX12345–123456
Результат приведен ниже.
pattern: "w{2}s*d{5}(–d{4})?"
1: TX77845
2: tx 77843
5: TX23456–3456
: –3456
6: TX77845–1234
: –1234
7: Tx77845
8: TX12345–1234
: –1234
Следует подчеркнуть несколько важных моментов.
• Мы не дали себя запутать неверно отформатированным кодом ZIP в строке, начинающейся символами ggg (кстати, что в нем неправильно?).
• В строке, содержащей символы zzz, мы нашли только первый код ZIP (мы ищем только один код в строке).
• В строках 5 и 6 мы нашли правильные суффиксы.
• В строке 7 мы нашли код ZIP, скрытый среди символов xxx.
• Мы нашли (к сожалению?) код ZIP, скрытый в строке TX12345–123456.
23.8. Синтаксис регулярных выражений
Мы рассмотрели довольно элементарный пример сравнения регулярных выражений. Настало время рассмотреть регулярные выражения (в форме, использованной в библиотеке regex) более полно и систематично.


23.8.1. Символы и специальные символы
Регулярные выражения определяют шаблон, который можно использовать для сопоставления символов из строки. По умолчанию символ в шаблоне соответствует самому себе в строке. Например, регулярное выражение (шаблон) "abc" соответствует подстроке abc строки Is there an abc here?
Реальная мощь регулярных выражений заключается в специальных символах и сочетаниях символов, имеющих особый смысл в шаблоне.

Например, выражение
x.y
соответствует любой строке, состоящей из трех символов, начинающейся с буквы x и заканчивающейся буквой y, например xxy, x3y и xay, но не yxy, 3xy или xy.
Обратите внимание на то, что выражения {...}, *, + и ? являются постфиксными операторами. Например, выражение d+ означает “одна или несколько десятичных цифр”.
Если хотите использовать в шаблоне один из специальных символов, вы должны сделать его управляющим, поставив перед ним обратную косую черту; например, символ + в шаблоне является оператором “один или несколько”, а символ + — это знак “плюс”.
23.8.2. Классы символов
Самые распространенные сочетания символов в сжатом виде представлены как специальные символы.

Символы в верхнем регистре означают “не вариант специального символа в нижнем регистре”. В частности, символ W означает “не буква”, а не “буква в верхнем регистре”.
Элементы третьего столбца (например, [[:digit:]]) представляют собой альтернативные синтаксические конструкции, использующие более длинные имена.
Как и библиотеки string и iostream, библиотека regex может обрабатывать большие наборы символов, такие как Unicode. Как и в случае библиотек string и iostream, мы просто упоминаем об этом, чтобы при необходимости читатели могли самостоятельно найти информацию. Обсуждение манипуляций текстами в кодировке Unicode выходит за рамки рассмотрения нашей книги.
23.8.3. Повторения
Повторяющиеся шаблоны задаются постфиксными операторами.

Например, выражение
Ax*
соответствует символу A, за котором не следует ни одного символа или следует несколько символов x:
A
Ax
Axx
Axxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Если мы требуем, чтобы символ x встречался хотя бы один раз, то следует использовать оператор +, а не *. Например, выражение
Ax+
соответствует символу A, за которым следует один или несколько символов x:
Ax
Axx
Axxxxxxxxxxxxxxxxxxxxxxxxxxxxx
но не
A
В общем случае необязательный символ (ни одного или несколько) указывается с помощью знака вопроса. Например, выражение
d–?d
соответствует двум цифрам с необязательным дефисом между ними:
1–2
12
но не