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

Переменная matches имеет тип smatch. Буква s означает “sub.” По существу, тип smatch представляет собой вектор частичных совпадений. Первый элемент matches[0] представляет собой полное совпадение. Мы можем интерпретировать элемент matches[i] как строку, если i. Итак, если для данного регулярного выражения максимальное количество частичных шаблонов равно N, выполняется условие matches.size==N+1.

  Что такое частичный шаблон (sub-pattern)? Можно просто сказать: “Все, что заключено в скобки внутри шаблона”. Глядя на шаблон "\\w{2}\\s*\\d{5}(–\\d{4})?", мы видим скобки вокруг четырехзначного кода ZIP. Таким образом, мы видим только один частичный шаблон, т.е. matches.size==2. Кроме того, можно догадаться, что у нас есть простой доступ к этим четырем последним цифрам. Рассмотрим пример.

while (getline(in,line)) {

  boost::smatch matches;

  if (boost::regex_search(line, matches, pat)) {

    cout << lineno << ": " << matches[0] << '\n'; // полное

                                                  // совпадение

    if (1

      cout << "\t: " << matches[1] << '\n'; // частичное

                                            // совпадение

  }

}

Строго говоря, мы не обязаны проверять выражение 1, поскольку уже рассмотрели шаблон, но к этому нас подталкивает легкая паранойя (поскольку мы экспериментируем с разными шаблонами, хранящимися в объекте 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.

<p id="AutBody_Root450"><strong>23.8. Синтаксис регулярных выражений</strong></p>

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

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже