Изучение [закрытых] регулярных выражений

166
задан 5 revs, 4 users 67% 7 January 2015 в 14:39
поделиться

1 ответ

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

  • ick
  • Nick
  • nick
  • Nnick
  • ] nNick
  • nnick
  • (и так далее)

Первое совпадение демонстрирует важный урок: * всегда успешен! Любой шаблон может совпадать ноль раз.

Еще несколько полезных примеров:

  • [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] , чтобы сопоставить «любые пробелы или любые непробельные символы», другими словами, что угодно.

765
ответ дан 23 November 2019 в 21:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: