Самая важная часть - это концепции. Как только вы поймете, как работают строительные блоки, различия в синтаксисе сведутся лишь к мягким диалектам. Слой поверх синтаксиса вашего механизма регулярных выражений - это синтаксис используемого вами языка программирования. Такие языки, как Perl, устраняют большую часть этого усложнения, но вам придется учитывать и другие соображения, если вы используете регулярные выражения в программе на языке C.
Если вы думаете о регулярных выражениях как о строительных блоках, которые вы можете смешивать и сопоставлять по своему усмотрению, это поможет вам научиться писать и отлаживать свои собственные шаблоны, а также понимать шаблоны, написанные другими.
По сути, самые простые регулярные выражения - это буквальные символы. Шаблон N
соответствует символу «N».
Регулярные выражения рядом друг с другом соответствуют последовательностям. Например, шаблон Ник
соответствует последовательности «N», за которой следует «i», за которой следует «c», за которой следует «k».
Если вы когда-либо использовали grep
в Unix - даже если только для поиска обычных строк - вы уже использовали регулярные выражения! ( re
в grep
относится к регулярным выражениям.)
Добавив немного сложности, вы можете сопоставить «Ник» или «ник» с шаблоном [Nn] ick
. Часть в квадратных скобках представляет собой символьный класс , что означает, что он соответствует ровно одному из заключенных символов. Вы также можете использовать диапазоны в классах символов, поэтому [a-c]
соответствует либо 'a', либо 'b', либо 'c'.
Выкройка .
является особенным: вместо сопоставления только буквальной точки, он сопоставляет любой символ † . Концептуально он такой же, как и действительно большой класс символов [-.?+%$ A-Za-z0-9 ...]
.
Думайте о классах персонажей как о меню: выберите только одно.
Использование .
может сэкономить вам много времени при вводе текста, кроме того, есть другие ярлыки для общих шаблонов. Допустим, вы хотите сопоставить цифру: один из способов записи - [0-9]
. Цифры часто совпадают, поэтому вместо них можно использовать ярлык \ d
. Другие: \ s
(пробел) и \ w
(символы слова: буквенно-цифровые символы или подчеркивание).
Варианты в верхнем регистре являются их дополнениями, поэтому \ S
соответствует, например, любому непробельному символу .
Оттуда вы можете повторять части вашего шаблона с квантификаторами . Например, шаблон ab? C
соответствует 'abc' или 'ac', потому что квантификатор ?
делает подшаблон, который он изменяет, необязательным.Другие кванторы:
*
(ноль или более раз) +
(один или несколько раз) {n}
(точно n раз) {n,}
(не менее n раз) {n, m}
(не менее n раз, но не более m раз) Объединяя некоторые из этих блоков, шаблон [Nn] * ick
совпадает со всеми
Первое совпадение демонстрирует важный урок: *
всегда успешен! Любой шаблон может совпадать ноль раз.
Еще несколько полезных примеров:
[0-9] +
(и его эквивалент \ d +
) соответствует любому неотрицательному целому числу \ d {4} - \ d {2} - \ d {2}
соответствует датам в формате 2019-01-01 Квантификатор изменяет образец слева от него. Вы можете ожидать, что 0abc + 0
будет соответствовать '0abc0', '0abcabc0' и т. Д., Но образец непосредственно слева от квантификатора плюс будет c
. Это означает, что 0abc + 0
соответствует '0abc0', '0abcc0', '0abccc0' и так далее.
Чтобы сопоставить одну или несколько последовательностей abc с нулями на концах, используйте 0 (abc) +0
. Скобки обозначают подшаблон, который можно количественно выразить как единицу. Механизмы регулярных выражений также часто сохраняют или «захватывают» ту часть входного текста, которая соответствует группе в скобках. Этот способ извлечения битов намного более гибкий и менее подвержен ошибкам, чем подсчет индексов и substr
.
Ранее мы видели один способ сопоставить «Ник» или «ник». Другой - с чередованием, как в Nick | nick
. Помните, что чередование включает все, что находится слева, и все, что справа. Используйте группирующие скобки, чтобы ограничить объем |
, например. , (Ник | ник)
.
В качестве другого примера, вы могли бы эквивалентно записать [ac]
как a | b | c
, но это, вероятно, будет неоптимальным, поскольку многие реализации предполагают, что альтернативы будут иметь длину больше, чем 1.
Хотя некоторые символы совпадают сами с собой, другие имеют особое значение. Шаблон \ d +
не соответствует обратной косой черте, за которой следует строчная буква D и знак плюса:чтобы получить это, мы использовали бы \\ d \ +
. Обратная косая черта удаляет особое значение следующего символа.
Квантификаторы регулярных выражений жадны. Это означает, что они сопоставляют столько текста, сколько возможно, позволяя успешно сопоставить весь шаблон.
Например, предположим, что ввод
«Привет», она сказала: «Как дела?»
Вы можете ожидать, что «. +»
будет соответствовать только «Привет» и тогда вы будете удивлены, когда увидите, что оно соответствует от «Hello» до «you?».
Чтобы переключиться с жадности на то, что вы считаете осторожным, добавьте в квантификатор дополнительный ?
. Теперь вы понимаете, как работает \ ((. +?) \)
, пример из вашего вопроса. Он соответствует последовательности буквальной левой круглой скобки, за которой следует один или несколько символов и заканчивается правой круглой скобкой.
Если вы введете «(123) (456)», то первым захватом будет «123». Нежадные квантификаторы хотят, чтобы остальная часть шаблона начала сопоставление как можно скорее.
(Что касается вашего недоразумения, я не знаю ни одного диалекта регулярных выражений, где ((. +?))
делал бы то же самое. Я подозреваю, что что-то потерялось при передаче где-то в способ.)
Используйте специальный шаблон ^
для сопоставления только в начале вашего ввода и $
для сопоставления только в конце. Создание «подставок для книг» с вашими выкройками, когда вы говорите: «Я знаю, что спереди и сзади, но дайте мне все, что находится между ними» - полезный прием.
Допустим, вы хотите сопоставить комментарии в форме
- Это комментарий -
вы должны написать ^ - \ s + (. +) \ S + - $
.
Регулярные выражения рекурсивны, поэтому теперь, когда вы понимаете эти основные правила, вы можете комбинировать их, как вам нравится.
†: Утверждение выше .
соответствует любому символу - это упрощение для педагогических целей, что не совсем верно.Точка соответствует любому символу, кроме символа новой строки, "\ n"
, но на практике вы редко ожидаете, что шаблон, такой как . +
, пересечет границу новой строки. Регулярные выражения Perl имеют переключатель / s
и Java Pattern.DOTALL
, например, для создания .
соответствует любому символу. Для языков, в которых нет такой функции, вы можете использовать что-то вроде [\ s \ S]
, чтобы сопоставить «любые пробелы или любые непробельные символы», другими словами, что угодно.