ОБНОВЛЕНИЕ 9/2021: см. дальнейшие объяснения / ответы в ответах на статьи!

Посмотрите мою статью REGEX COOKBOOK о наиболее часто используемых (и наиболее востребованных) регулярных выражениях 🎉

Регулярные выражения (regex или regexp) чрезвычайно полезны при извлечении информации из любого текста путем поиска одного или нескольких совпадений с определенным шаблоном поиска (то есть с определенной последовательностью символов ASCII или Unicode).

Сферы применения варьируются от проверки до анализа / замены строк, передачи данных в другие форматы и парсинга веб-страниц.

Одна из самых интересных функций заключается в том, что после того, как вы изучите синтаксис, вы сможете использовать этот инструмент (почти) на всех языках программирования (JavaScript, Java, VB, C #, C / C ++, Python, Perl, Ruby , Delphi, R, Tcl и многие другие) с малейшими различиями в поддержке наиболее продвинутых функций и версий синтаксиса, поддерживаемых движками).

Давайте начнем с рассмотрения некоторых примеров и объяснений.

Основные темы

Якоря - ^ и $

^The        matches any string that starts with The -> Try it!
end$        matches a string that ends with end
^The end$   exact string match (starts and ends with The end)
roar        matches any string that has the text roar in it

Квантификаторы - * +? и {}

abc*        matches a string that has ab followed by zero or more c -> Try it!
abc+        matches a string that has ab followed by one or more c
abc?        matches a string that has ab followed by zero or one c
abc{2}      matches a string that has ab followed by 2 c
abc{2,}     matches a string that has ab followed by 2 or more c
abc{2,5}    matches a string that has ab followed by 2 up to 5 c
a(bc)*      matches a string that has a followed by zero or more copies of the sequence bc
a(bc){2,5}  matches a string that has a followed by 2 up to 5 copies of the sequence bc

Оператор ИЛИ - | или []

a(b|c)     matches a string that has a followed by b or c (and captures b or c) -> Try it!
a[bc]      same as previous, but without capturing b or c

Классы символов - \ d \ w \ s и.

\d         matches a single character that is a digit -> Try it!
\w         matches a word character (alphanumeric character plus underscore) -> Try it!
\s         matches a whitespace character (includes tabs and line breaks)
.          matches any character -> Try it!

Используйте оператор . осторожно, так как часто класс или инвертируемый символьный класс (который мы рассмотрим далее) быстрее и точнее.

\d, \w и \s также представляют свои отрицания с помощью \D, \W и \S соответственно.

Например, \D выполнит обратное совпадение относительно совпадения, полученного с помощью \d.

\D         matches a single non-digit character -> Try it!

Чтобы понимать буквально, вы должны экранировать символы ^.[$()|*+?{\ обратной косой чертой \, поскольку они имеют особое значение.

\$\d       matches a string that has a $ before one digit -> Try it!

Обратите внимание, что вы также можете сопоставлять непечатаемые символы, такие как табуляция \t, новые строки \n, возврат каретки \r.

Флаги

Мы учимся создавать регулярные выражения, но забываем основную концепцию: флаги.

Регулярное выражение обычно входит в эту форму /abc/, где шаблон поиска разделен двумя символами косой черты /. В конце мы можем указать флаг с этими значениями (мы также можем комбинировать их друг с другом):

  • g (глобальный) не возвращается после первого совпадения, возобновляя последующие поиски с конца предыдущего совпадения.
  • m (многострочный) при включении ^ и $ будут соответствовать началу и концу строки, а не всей строке
  • i (нечувствительный) делает все выражение нечувствительным к регистру (например, /aBc/i будет соответствовать AbC)

Промежуточные темы

Группировка и захват - ()

a(bc)           parentheses create a capturing group with value bc -> Try it!
a(?:bc)*        using ?: we disable the capturing group -> Try it!
a(?<foo>bc)     using ?<foo> we put a name to the group -> Try it!

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

Если мы решим присвоить группам имена (используя (?<foo>...)), мы сможем извлекать значения групп, используя результат сопоставления, например словарь, где ключи будут именем каждой группы.

Выражения в квадратных скобках - []

[abc]            matches a string that has either an a or a b or a c -> is the same as a|b|c -> Try it!
[a-c]            same as previous
[a-fA-F0-9]      a string that represents a single hexadecimal digit, case insensitively -> Try it!
[0-9]%           a string that has a character from 0 to 9 before a % sign
[^a-zA-Z]        a string that has not a letter from a to z or from A to Z. In this case the ^ is used as negation of the expression -> Try it!

Жадный и ленивый матч

Квантификаторы (* + {}) - это жадные операторы, поэтому они расширяют соответствие, насколько это возможно, с помощью предоставленного текста.

Например, <.+> соответствует <div>simple div</div> в This is a <div> simple div</div> test. Чтобы поймать только тег div, мы можем использовать ?, чтобы сделать его ленивым:

<.+?>            matches any character one or more times included inside < and >, expanding as needed -> Try it!

Обратите внимание, что в лучшем решении следует избегать использования . в пользу более строгого регулярного выражения:

<[^<>]+>         matches any character except < or > one or more times included inside < and > -> Try it!

Дополнительные темы

Границы - \ b и \ B

\babc\b          performs a "whole words only" search -> Try it!

\b представляет собой привязку, такую ​​как курсор (аналогично $ и ^), совпадающие с позициями, где одна сторона - это слово символ (например, \w) и другая сторона не является словом символом (например, это может быть начало строки или пробел).

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

\Babc\B          matches only if the pattern is fully surrounded by word characters -> Try it!

Обратные ссылки - \ 1

([abc])\1              using \1 it matches the same text that was matched by the first capturing group -> Try it!
([abc])([de])\2\1      we can use \2 (\3, \4, etc.) to identify the same text that was matched by the second (third, fourth, etc.) capturing group -> Try it!
(?<foo>[abc])\k<foo>   we put the name foo to the group and we reference it later (\k<foo>). The result is the same of the first regex -> Try it!

Взгляд вперед и назад - (? =) и (? ‹=)

d(?=r)       matches a d only if is followed by r, but r will not be part of the overall regex match -> Try it!
(?<=r)d      matches a d only if is preceded by an r, but r will not be part of the overall regex match -> Try it!

Вы также можете использовать оператор отрицания!

d(?!r)       matches a d only if is not followed by r, but r will not be part of the overall regex match -> Try it!
(?<!r)d      matches a d only if is not preceded by an r, but r will not be part of the overall regex match -> Try it!

Резюме

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

  • проверка данных (например, проверьте, правильно ли сформирована временная строка i)
  • очистка данных (особенно веб-очистка, поиск всех страниц, содержащих определенный набор слов, в конечном итоге в определенном порядке)
  • обработка данных (преобразование данных из «сырых» в другой формат)
  • синтаксический анализ строки (например, захват всех параметров URL GET, захват текста в скобках)
  • замена строки (например, даже во время сеанса кода с использованием общей IDE для перевода класса Java или C # в соответствующий объект JSON - замените «;» на «,» сделайте это строчными буквами, избегайте объявления типа и т. д.)
  • выделение синтаксиса, переименование файлов, анализ пакетов и многие другие приложения, использующие строки (где данные не обязательно должны быть текстовыми)

Получайте удовольствие и не забудьте порекомендовать статью, если она вам понравилась 💚

ОБНОВЛЕНИЕ! Посмотрите мою новую REGEX COOKBOOK о наиболее часто используемых (и наиболее востребованных) регулярных выражениях 🎉