Я не понимаю регулярных выражений. Можете ли вы объяснить их мне в простой форме? Если есть какие-либо онлайн-инструменты или книги, вы также можете ссылаться на них?
Изучение регулярных выражений
Ответ 1
Наиболее важной частью являются концепции. Как только вы понимаете, как работают строительные блоки, различия в синтаксисе составляют чуть больше, чем простые диалекты. Слой поверх вашего синтаксиса механизма регулярных выражений - это синтаксис языка программирования, который вы используете. Такие языки, как Perl, снимают большую часть этого усложнения, но вам следует учитывать и другие соображения, если вы используете регулярные выражения в программе на Си.
Если вы думаете о регулярных выражениях как о строительных блоках, которые вы можете смешивать и сопоставлять по своему усмотрению, это поможет вам научиться писать и отлаживать собственные шаблоны, а также понимать шаблоны, написанные другими.
Начните с простого
Концептуально, самые простые регулярные выражения - это буквальные символы. Шаблон N соответствует символу "N".
Регулярные выражения рядом друг с другом соответствуют последовательностям. Например, шаблон Nick соответствует последовательности "N", за которой следует "i", затем "c" и "k".
Если вы когда-либо использовали grep в Unix - даже если только для поиска обычных строк - вы уже использовали регулярные выражения! (re в grep относится к регулярным выражениям.)
Заказать из меню
Добавляя небольшую сложность, вы можете сопоставить 'Nick' или 'Nick' с шаблоном [Nn]ick. Часть в квадратных скобках является классом символов, что означает, что он соответствует точно одному из вложенных символов. Вы также можете использовать диапазоны в классах символов, поэтому [ac] соответствует '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 соответствует всем
- Ик
- Ник
- Ник
- 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).
В другом примере вы могли бы эквивалентно написать [ac] как a|b|c, но это, вероятно, будет неоптимальным, поскольку во многих реализациях предполагается, что альтернативы будут иметь длину больше 1.
Спасаясь
Хотя некоторые персонажи соответствуют друг другу, другие имеют особое значение. Шаблон \d+ не соответствует обратной косой \d+ за которой следует строчная буква D с последующим знаком плюс: чтобы получить это, мы будем использовать \\d\+. Обратная косая черта удаляет специальное значение из следующего символа.
Жадность
Квантификаторы регулярных выражений являются жадными. Это означает, что они соответствуют как можно большему количеству текста, в то же время позволяя успешно сопоставить весь шаблон.
Например, скажем, вход
"Привет, - сказала она, - как дела?"
Вы можете ожидать, что ".+" Будет соответствовать только "Hello", и вы будете удивлены, когда увидите, что оно совпадает с "Hello" на всем протяжении "you?".
Чтобы переключиться с жадного на то, что вы считаете осторожным, добавьте лишнее ? в квантификатор. Теперь вы понимаете, как работает \((.+?)\) Пример из вашего вопроса. Он соответствует последовательности буквальной левой круглой скобки, за которой следуют один или несколько символов и оканчивающейся правой круглой скобкой.
Если вы введете "(123) (456)", то первый захват будет "123". Нежадные квантификаторы хотят, чтобы остальная часть шаблона начала сопоставление как можно скорее.
(Что касается вашей путаницы, я не знаю ни одного диалекта регулярного выражения, где ((.+?)) Делал бы то же самое. Я подозреваю, что что-то потеряно при передаче где-то по пути.)
Якоря
Используйте специальный шаблон ^ для сопоставления только в начале ввода и $ для сопоставления только в конце. Создание "форзацев" с вашими шаблонами, когда вы говорите: "Я знаю, что впереди и сзади, но дай мне все между" - это полезная техника.
Скажем, вы хотите сопоставить комментарии формы
-- This is a comment --
Вы бы написали ^--\s+(.+)\s+--$.
Построй свой собственный
Регулярные выражения являются рекурсивными, поэтому теперь, когда вы понимаете эти основные правила, вы можете комбинировать их по своему усмотрению.
Инструменты для написания и отладки регулярных выражений:
- RegExr (для JavaScript)
- Perl: YAPE: Regex Объясните
- Regex Coach (двигатель поддерживается CL-PPCRE)
- RegexPal (для JavaScript)
- Регулярные выражения Интернет-тестер
- Regex Buddy
- Regex 101 (для PCRE, JavaScript, Python, Golang)
- Visual RegExp
- Expresso (для .NET)
- Рубулярный (для Руби)
- Библиотека регулярных выражений (предопределенные регулярные выражения для распространенных сценариев)
- Txt2RE
- Regex Tester (для JavaScript)
- Regex Storm (для .NET)
- Debuggex (визуальный тестер регулярных выражений и помощник)
книги
- Освоение регулярных выражений, 2-е издание и 3-е издание.
- Шпаргалка регулярных выражений
- Regex Cookbook
- Учите себя регулярным выражениям
Бесплатные ресурсы
- RegexOne - учитесь с помощью простых интерактивных упражнений.
- Регулярные выражения - все, что вы должны знать (PDF Series)
- Сводка по синтаксису регулярных выражений
- Как работают регулярные выражения
сноска
†: утверждение выше этого . Соответствие любому символу является упрощением для педагогических целей, что не совсем верно. Точка соответствует любому символу, кроме новой строки, "\n", но на практике вы редко ожидаете, что шаблон, такой как .+, Пересечет границу новой строки. В регулярных выражениях Perl есть, например, ключ /s и Java Pattern.DOTALL . соответствовать любому персонажу вообще. Для языков, у которых нет такой возможности, вы можете использовать что-то вроде [\s\S] для соответствия "любому пробелу или любому непробелу", другими словами, чему угодно.