Подвыражения обычно используются для проверки данных, которые должны соответствовать некоему определенному формату. Например, в Америке номера телефонов имеют десять цифр, включая код города и местный номер из семи цифр. Код города зачастую, но не всегда, заключен в круглые скобки. Остальные семь цифр могут быть отделены тире, точкой или пробелом либо не отделяться вообще. Данные в некоторых из этих форматов могли бы быть приемлемы, а в других — нет. Процесс будет состоять из двух этапов: сначала используем регулярное выражение для поиска последовательностей, которые могли бы быть номерами телефонов, а затем вызовем функцию для окончательной проверки правильности данных.
Прежде чем написать схему номеров телефона, необходимо рассмотреть еще несколько аспектов языка регулярных выражений на языке ECMAScript.
• \{d}
представляет одиночную цифру, а \{d}{n}
— последовательность из n
цифр. (Например, \{d}{3}
соответствует последовательности из трех цифр.)
• Набор символов в квадратных скобках позволяет задать соответствие любому из трех символов. (Например, [-.]
соответствует тире, точке или пробелу. Обратите внимание: у точки в квадратных скобках нет никакого специального смысла.)
• Компонент, следующий за символом '?'
, не обязательный. (Например, \{d}{3}[-. ]?\{d}{4}
соответствует трем цифрам, сопровождаемым опциональными тире, точкой или пробелом и еще четырьмя цифрами. Этой схеме соответствовало бы 555-0132
, или 555.0132
, или 555 0132
, или 5550132
).
• Как и в языке С++, в ECMAScript символ за наклонной чертой означает, что он представляет себя, а не специальное значение. Поскольку данная схема включает круглые скобки, являющиеся специальными символами в языке ECMAScript, круглые скобки, являющиеся частью схемы, следует представить как \(
или \)
.
Поскольку наклонная черта влево является специальным символом в языке С++, когда он встречается в схеме, следует добавить вторую наклонную черту, чтобы указать языку С++, что имеется в виду символ \
. Следовательно, чтобы представить регулярное выражение \{d}{3}
, нужно написать \\{d}{3}
.
Для проверки номеров телефонов следует обратиться к компонентам схемы. Например, необходимо проверить, что если номер использует открывающую круглую скобку для кода города, то он использует также закрывающую скобку после него. В результате такой номер, как (908.555.1800
, следует отклонить.
Для определения такого соответствия необходимо регулярное выражение, использующее подвыражения. Каждое подвыражение заключается в пару круглых скобок:
//
//
//
"(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ]?)(\\d{4})";
Поскольку схема использует круглые скобки, а также из-за использования наклонных черт, эту схему трудно прочитать (и написать!). Проще всего прочитать ее по каждому отдельному (заключенному в скобки) подвыражению.
1. (\\()?
необязательная открывающая скобка для кода города.
2. (\\d{3})
код города.
3. (\\))?
необязательная закрывающая скобка для кода города.
4. ([-. ])?
необязательный разделитель после кода города.
5. (\\d{3})
следующие три цифры номера.
6. ([-. ])?
другой необязательный разделитель.
7. (\\d{4})
последние четыре цифры номера.
Следующий код использует эту схему для чтения файла и находит данные, соответствующие общей схеме телефонных номеров. Для проверки допустимости формата номеров используется функция valid()
:
string phone =
"(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ]?)(\\d{4})";
regex r(phone); //
smatch m;
string s;
// прочитать все записи из входного файла
while (getline(cin, s)) {
//
for (sregex_iterator it(s.begin(), s.end(), r), end_it;
it != end_it; ++it)
//
if (valid(*it))
cout << "valid: " << it->str() << endl;
else
cout << "not valid: " << it->str() << endl;
}