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

Я не очень понимаю регулярные выражения. Можете ли вы объяснить их мне в простой для понимания форме? Если есть какие-либо онлайн-инструменты или книги, не могли бы вы также дать ссылку на них?

1 ответ

Наиболее важной частью являются концепции. Как только вы понимаете, как работают строительные блоки, различия в синтаксисе составляют чуть больше, чем простые диалекты. Слой поверх синтаксиса вашего механизма регулярных выражений - это синтаксис языка программирования, который вы используете. Такие языки, как Perl, снимают большую часть этого усложнения, но вам следует учитывать и другие соображения, если вы используете регулярные выражения в программе на Си.

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

Начните с простого

Концептуально, самые простые регулярные выражения - это буквальные символы. Шаблон N соответствует символу "N".

Регулярные выражения рядом друг с другом соответствуют последовательностям. Например, шаблон Nick соответствует последовательности "N", за которой следует "i", затем "c" и "k".

Если вы когда-либо использовали grep в Unix - даже если только для поиска обычных строк - вы уже использовали регулярные выражения! (The re в grep относится к регулярным выражениям.)

Заказать из меню

Добавляя небольшую сложность, вы можете сопоставить 'Nick' или 'Nick' с шаблоном [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 раз, но не более м раз)

Соединяя некоторые из этих блоков, шаблон [Nn]*ick соответствует всем

  • Ик
  • Ник
  • Ник
  • 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, Помните, что чередование включает в себя все слева и все справа. Используйте скобки для группировки, чтобы ограничить область действия |например, (Nick|nick),

Для другого примера вы могли бы эквивалентно написать [a-c] как a|b|c, но это, вероятно, будет неоптимальным, потому что во многих реализациях предполагается, что альтернативы будут иметь длину больше 1.

Спасаясь

Хотя некоторые персонажи соответствуют друг другу, другие имеют особое значение. Шаблон \d+ не соответствует обратной косой черте, за которой следует строчная буква D с последующим знаком плюс: чтобы получить это, мы будем использовать \\d\+, Обратная косая черта удаляет специальное значение из следующего символа.

Жадность

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

Например, скажем, вход

"Привет, - сказала она, - как дела?"

Вы можете ожидать ".+" соответствовать только "Hello", и затем вы будете удивлены, когда увидите, что он совпадает с "Hello" на всем протяжении "you?".

Чтобы переключиться с жадного на то, что вы можете считать осторожным, добавьте дополнительный ? в квантификатор. Теперь вы понимаете, как \((.+?)\), пример из твоего вопроса работает. Он соответствует последовательности буквальной левой круглой скобки, за которой следуют один или несколько символов и оканчивающейся правой круглой скобкой.

Если вы введете "(123) (456)", то первый захват будет "123". Нежадные квантификаторы хотят, чтобы остальная часть шаблона начала сопоставление как можно скорее.

(Что касается вашей путаницы, я не знаю ни одного диалекта регулярного выражения, где ((.+?)) сделал бы то же самое. Я подозреваю, что что-то потеряно при передаче где-то по пути.)

Якоря

Используйте специальный шаблон ^ соответствовать только в начале вашего ввода и $ соответствовать только в конце. Создание "форзацев" с вашими шаблонами, когда вы говорите: "Я знаю, что находится впереди и сзади, но дай мне все, что между", - это полезная техника.

Скажем, вы хотите сопоставить комментарии формы

-- This is a comment --

ты бы написал ^--\s+(.+)\s+--$,

Построй свой собственный

Регулярные выражения являются рекурсивными, поэтому теперь, когда вы понимаете эти основные правила, вы можете комбинировать их по своему усмотрению.

Инструменты для написания и отладки регулярных выражений:

книги

Бесплатные ресурсы

сноска

†: утверждение выше, что . Соответствие любому символу является упрощением для педагогических целей, что не совсем верно. Точка соответствует любому символу, кроме новой строки, "\n", но на практике вы редко ожидаете такой шаблон, как.+ пересечь границу новой строки. Perl регулярные выражения имеют/s свич и яваPattern.DOTALL, например, сделать . соответствовать любому персонажу вообще. Для языков, которые не имеют такой функции, вы можете использовать что-то вроде [\s\S] соответствовать "любому пробелу или любому непробелу", другими словами, чему угодно.

Другие вопросы по тегам