Независимо от того, нужно ли вам извлечь адреса электронной почты из набора HTML-документов или прочесать огромные файлы журналов в поисках ошибок «иголка в стоге сена», регулярные выражения предоставляют мощный инструмент для поиска текста.

Поскольку они в основном состоят из последовательностей токенов с несколько неочевидным значением, регулярные выражения (или регулярные выражения) могут быть сложными для расшифровки. Умеренная кривая обучения, чтобы понять, как создать точное регулярное выражение, очень полезна и может сэкономить часы ручного поиска текста.

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

Базовое соответствие

Регулярные выражения состоят из набора токенов, используемых для определения определенного шаблона. Затем этот шаблон можно сравнить со строкой, чтобы определить, соответствует ли он шаблону в целом или части строки соответствуют шаблону. В большинстве языков регулярные выражения помещаются между косой чертой. Внутри этих косых черт вы найдете ряд токенов, самые основные из которых — буквальные строковые выражения.

/efg/

abcdefghijk

В приведенном выше примере шаблон, определенный между косыми чертами, регистрирует совпадение в образце строки. Часть строки «efg» явно ищется в регулярном выражении и, таким образом, возвращается как совпадение (выделено жирным шрифтом).

Чтобы сделать поиск более гибким, скобки позволяют определить несколько возможных совпадений. Если вы искали в каталоге любого человека по имени «Тед» или «Нед», вы могли бы использовать одно регулярное выражение с квадратными скобками, обозначающими, что должны быть приняты как T, так и N. .

/[TN]ed/

Барбара Терри Нед Джоэл Тед Эдди

Другие, более незнакомые символы, часто начинающиеся с обратной косой черты, можно использовать для более сложных поисков. Если вы хотите найти серийный номер, сопоставив любую цифру, вам не нужно будет записывать каждую цифру от 0 до 9, вместо этого вы можете использовать токен \d, который символизирует все цифры.

/\d/

abc 123 def 456 ghi

Ряд других полезных подобных токенов перечислены ниже:

  • . — соответствует любому символу, кроме новой строки
  • \w — соответствует любому символу слова (не цифре и не пробелу)
  • \W — соответствует любому символу, не являющемуся словом
  • \s — соответствует любому пробельному символу, такому как пробел или новая строка
  • \S — соответствует любому непробельному символу
  • \D — соответствует любому нецифровому символу

Группы захвата

/(goose)/

утка утка гусь утка утка гусь

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

/(goose){2}/

утка утка гусь утка утка гусь

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

В очень простом примере в регулярном выражении /(goose)(duck)\1/ \1 можно прочитать как (goose), поскольку оно указывает на первую группу захвата. \2 будет относиться к (duck), поскольку он относится ко второму захвату. Этот шаблон можно использовать для обратной ссылки на любое количество групп.

В качестве более интересного примера рассмотрим, что происходит, когда мы выполняем обратную ссылку на один из общих маркеров соответствия, перечисленных в предыдущем разделе.

/(\w)b\1/

yаба даба doo yabo dabo doo

Здесь группа захвата соответствует любому символу слова, а b соответствует только буквальному символу b. Затем обратная ссылка соответствует результату исходной группы захвата. По сути, это соответствует любому вхождению буквы b с непосредственно предшествующими и последующими символами, если эти символы совпадают.

Если вы хотите определить синтаксическую единицу, но исключить ее из этих обратных ссылок, просто используйте группу без захвата. Синтаксис /(?:goose)/.

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

/(?<myGroup>goose)\k<myGroup>/

Повторение

Регулярные выражения предлагают ряд инструментов для сопоставления повторяющихся сегментов строки. Они изложены ниже.

  • (abc)* — соответствует любому количеству повторений «abc», даже нулю
  • (abc)+ — соответствует хотя бы одному повторению «abc»
  • (abc)? — соответствует любому нулевому или одному повторению «abc», но не более
  • (abc){n} — точно соответствует n повторениям слова «abc».
  • (abc){n,} — соответствует как минимум n повторениям слова «abc».
  • (abc){n,m} — соответствует от n до m повторений слова «abc».

Обратите внимание, что повторения должны быть непосредственно примыкающими друг к другу, без каких-либо несовпадающих символов между ними.

Границы

Граничные маркеры можно использовать, чтобы убедиться, что совпадения примыкают к определенным элементам. Например, вы можете убедиться, что вы сопоставляете только те последовательности, которые находятся в самом конце строки.

/(goose)$/

утка утка гусь утка утка гусь

Обратите внимание, что это отличается от привязки \z, которая соответствует концу всей строки, а не только строки.

Точно так же совпадение привязки ^ можно поместить в начало выражения, чтобы гарантировать, что совпадение происходит только в начале строки.

Внутри строки отдельные слова могут быть изолированы с помощью привязки границы \b слов. Это полезно, например, если вы пытаетесь сопоставить слово, которое может встречаться в других более длинных словах.

/\b(she)\b/

линяет она овец она пастух

Расширенные границы

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

/(?<!b)(123)/

a123 b123 c123 d123

Здесь выражение (?<!b) представляет собой отрицательное ретроспективное выражение, которое гарантирует, что последующему выражению не будет предшествовать непосредственно буква "b". Противоположное выражение, положительный просмотр назад, выглядит как (?=b) и гарантирует, что только строки «123», которым начинается непосредственно с «b», будут зарегистрированы как совпадения.

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

Спасательные символы

Иногда вам может понадобиться искать буквальные вхождения специальных токенов регулярных выражений. В таких случаях просто ставьте перед символом обратную косую черту. В то время как . будет соответствовать любым символам вообще, \. будет соответствовать только вхождению фактического символа точки.

Дополнительные ресурсы

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

Онлайн-тестер регулярных выражений — в свободном доступе есть много подобных тестеров, которые вы можете найти с помощью быстрого поиска, но мне особенно нравится этот, потому что он обеспечивает более широкую поддержку нескольких языков программирования. Большинство реализуют только поддержку регулярных выражений Javascript, в которой отсутствуют некоторые ключевые функции.

Учебник по регулярным выражениям — Medium — Шпаргалка Джонни Фокса на примере — это феноменальное глубокое погружение во многие ключевые концепции регулярных выражений.

Справочник по регулярным выражениям — отличный упрощенный обзор синтаксиса регулярных выражений, полезный для быстрого ознакомления с определенным типом сопоставления.

Шпаргалка по регулярным выражениям — удобно добавить в закладки. Чистый и минимальный с полезной информацией о различиях между языковыми реализациями.