Литмир - Электронная Библиотека
A
A

: –1234

Следует подчеркнуть несколько важных моментов.

• Мы не дали себя запутать неверно отформатированным кодом ZIP в строке, начинающейся символами ggg (кстати, что в нем неправильно?).

• В строке, содержащей символы zzz, мы нашли только первый код ZIP (мы ищем только один код в строке).

• В строках 5 и 6 мы нашли правильные суффиксы.

• В строке 7 мы нашли код ZIP, скрытый среди символов xxx.

• Мы нашли (к сожалению?) код ZIP, скрытый в строке TX12345–123456.

23.8. Синтаксис регулярных выражений

Мы рассмотрели довольно элементарный пример сравнения регулярных выражений. Настало время рассмотреть регулярные выражения (в форме, использованной в библиотеке

regex
) более полно и систематично.

 

Программирование. Принципы и практика использования C++ Исправленное издание - _001.png
 Регулярные выражения (regular expressions, regexps или regexs), по существу, образуют небольшой язык для выражения символьных шаблонов. Этот мощный (выразительный) и лаконичный язык иногда выглядит довольно таинственным. За десятилетия использования регулярных выражений в этом языке появилось много тонких свойств и несколько диалектов. Здесь мы опишем подмножество регулярных выражений (большое и полезное), которое, возможно, в настоящее время является наиболее распространенным диалектом (язык Perl). Если читателям понадобится более подробная информация о регулярных выражениях или возникнет необходимость объяснить их другим людям, они могут найти все, что нужно, в веб. Существует огромное количество учебников (очень разного качества) и спецификаций. В частности, в веб легко найти спецификацию
boost::regex
и ее эквивалент, принятый Комитетом по стандартизации (WG21 TR1).

 

Программирование. Принципы и практика использования C++ Исправленное издание - _001.png
 Библиотека
boost::regex
поддерживает также системы обозначений языков ECMAScript, POSIX и awk, а также утилит grep и egrep. Кроме того, она содержит массу возможностей для поиска. Это может оказаться чрезвычайно полезным, особенно, если вам необходимо сравнить шаблон, описанный на другом языке. Если вам понадобятся языковые средства, которые выходят за рамки тем, которые мы описываем, поищите их самостоятельно. Однако помните, что использование как можно большего числа свойств — это не самоцель качественного программирования. При любой возможности постарайтесь сжалиться над бедным программистом, который будет эксплуатировать вашу программу (возможно, им окажетесь вы сами через несколько месяцев), читать ее и пытаться разобраться в вашем коде: код следует писать так, чтобы он не был заумным без особой причины и не содержал малопонятных мест.

23.8.1. Символы и специальные символы

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

Реальная мощь регулярных выражений заключается в специальных символах и сочетаниях символов, имеющих особый смысл в шаблоне.

Программирование. Принципы и практика использования C++ Исправленное издание - _282.png

Например, выражение

x.y

соответствует любой строке, состоящей из трех символов, начинающейся с буквы

x
и заканчивающейся буквой
y
, например
xxy
,
x3y
и
xay
, но не
yxy
,
3xy
или
xy
.

Обратите внимание на то, что выражения

{...}
,
*
,
+
и
?
являются постфиксными операторами. Например, выражение \d+ означает “одна или несколько десятичных цифр”.

Если хотите использовать в шаблоне один из специальных символов, вы должны сделать его управляющим, поставив перед ним обратную косую черту; например, символ

+
в шаблоне является оператором “один или несколько”, а символ
\+
— это знак “плюс”.

23.8.2. Классы символов

Самые распространенные сочетания символов в сжатом виде представлены как специальные символы.

Программирование. Принципы и практика использования C++ Исправленное издание - _283.png

Символы в верхнем регистре означают “не вариант специального символа в нижнем регистре”. В частности, символ \W означает “не буква”, а не “буква в верхнем регистре”.

Элементы третьего столбца (например,

[[:digit:]]
) представляют собой альтернативные синтаксические конструкции, использующие более длинные имена.

Как и библиотеки

string
и
iostream
, библиотека
regex
может обрабатывать большие наборы символов, такие как Unicode. Как и в случае библиотек
string
и
iostream
, мы просто упоминаем об этом, чтобы при необходимости читатели могли самостоятельно найти информацию. Обсуждение манипуляций текстами в кодировке Unicode выходит за рамки рассмотрения нашей книги.

23.8.3. Повторения

Повторяющиеся шаблоны задаются постфиксными операторами.

Программирование. Принципы и практика использования C++ Исправленное издание - _284.png

Например, выражение

Ax*

соответствует символу A, за котором не следует ни одного символа или следует несколько символов x:

A

Ax

Axx

Axxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Если мы требуем, чтобы символ

x
встречался хотя бы один раз, то следует использовать оператор
+
, а не
*
. Например, выражение

Ax+

соответствует символу A, за которым следует один или несколько символов x:

Ax

Axx

Axxxxxxxxxxxxxxxxxxxxxxxxxxxxx

но не

A

В общем случае необязательный символ (ни одного или несколько) указывается с помощью знака вопроса. Например, выражение

\d–?\d

соответствует двум цифрам с необязательным дефисом между ними:

1–2

12

но не

1––2

Для задания конкретного количества вхождений или конкретного диапазона вхождений используются фигурные скобки. Например, выражение

325
{"b":"847443","o":1}