Skip to content

The best regular expression patterns collection you have ever seen. Коллекция регулярных выражений.

License

Notifications You must be signed in to change notification settings

rin-nas/regexp-patterns-library

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

93 Commits
 
 
 
 
 
 

Repository files navigation

Регулярные выражения

Когда применять, а когда не применять регулярные выражения?

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

Диалекты

  • PCRE, применяется в PHP и др. ПО
  • ECMA 262, применяется в JavaScript
  • есть и другие достойные внимания, но в этом документе не рассматриваются

Функции и методы объектов для обработки строк регулярными выражениями в языках программирования

Тип обработки JavaScript PHP
Проверка соответствия (валидация) RegExp.test() preg_match(), preg_grep()
Поиск и захват подстрок RegExp.exec(), String.match(), String.search() preg_match_all()
Поиск, захват и замена подстрок String.replace() preg_replace(), preg_replace_callback(), preg_replace_callback_array(), preg_filter()
Поиск и разбиение на подстроки String.split() preg_split()

Виды соответствия

  • Полное — вся строка соответствует шаблону регулярного выражения, которое всегда начинается с ^ и заканчивается на $.
  • Частичное — часть строки соответствует шаблону регулярного выражения. Наличие символов ^ и $ опционально.

Полное соответствие обычно используют для валидации (проверки) строк на соответствие или не соответствие регулярному выражению. А частичное — для синтаксического анализа (парсинга) и лексического анализа (токенизации) строк.

Из частичного соответствия очень легко сделать полное, указав ^ в начале и $ в конце. В обратную сторону — сложнее, т.к. при необходимости необходимо явно указывать границы начала и конца искомой подстроки. Обычно это делают через (?<!…) и (?!…) соответственно.

Почему регулярные выражения работают медленно?

Главная проблема медлительности — многочисленные откаты в случае неудачи в одной из веток поиска, которые могут привести к превышению максимального времени выполнения. Подробнее см. Catastrophic Backtracking.

  • Пример долго выполняющегося регулярного выражения PCRE и его оптимизированной версии, работающей почти в 10 раз быстрее: PCRE

Как писать быстро работающие регулярные выражения?

  1. Используйте атомарную группировку (?>…) и/или однократные квантификаторы: …?+, …*+, …++. В диалекте JS нет такой встроенной возможности, но можно использовать конструкцию типа (?=(…))\1, которая является аналогом.
  2. Не используйте вложенные циклы типа (…+)+. Используйте конструкции типа (?!…)(…)+, (?=…)(…)+, (…)+(?<!…), (…)+(?<=…).
  3. В случае отсутствия ^ задавайте явно границу начала совпадения через \b или (?<!…). В случае отсутствия $ задавайте явно границу совпадения через \b или (?!…).
  4. Замените нежадные квантификаторы типа .*? на жадные. Но часть рег. выражения нужно будет немного переписать и усложнить для увеличения скорости.
  5. Не используйте флаг /u (юникод в PCRE). Возможно, часть рег. выражения нужно будет немного переписать и усложнить для увеличения скорости.

Что делать, если диалект регулярного выражения не поддерживает нужной мне возможности?

  1. Регулярные выражения PCRE пока поддерживают просмотр назад только с фиксированной длиной. Т.е. внутри (?<!…) нельзя использовать квантификаторы ?, *, +, {…,…}. Но есть способ обойти это ограничение, используя \K.
  2. Регулярные выражения JS пока не поддерживают всех возможностей PCRE, но есть готовые решения:
    • Библиотека XRegExp, которая расширяет стандартные возможности рег. выражений в JS до уровня PCRE.
    • String.prototype.matchRecursive() — реализация JavaScript метода String.match() с учётом рекурсии: JS Fiddle
    • Генератор регулярного выражения до заданной глубины рекурсии (?R) (TODO сделать форму ввода): JS Fiddle

Какие онлайн сервисы существуют для обработки строк регулярными выражениями?

Используйте сервис regex101.com для написания и тестирования ваших регурярных выражений, а так же для поиска и замены подстрок через регулярные выражения в диалектах PRCE, JS, Python, Golang.

Склад готовых регулярных выражений

Каждое регулярное выражение написано так, чтобы оно

  • работало максимально быстро (по советам выше)
  • было читабельным с выделением логических частей (используется флаг /x) и описанием в комментариях (#)

Числа

  • Целые: /^[-−]? (?:[1-9]\d*|0) $/sx
  • Целые и десятичные: /^[-−]? (?:[1-9]\d*|0) (?:\.\d+)? $/sx
  • Денежный формат: /^[-−]? (?:[1-9]\d*|0) (?:\.\d{1,2})? $/sx
  • Число с разделением тысячных через запятую и десятичными: PCRE

Дата и время

нестрогая валидация

  • Дата в формате ГГГГ-ММ-ДД: /^\d{4}-\d{2}-\d{2}$/sSX
  • Время в формате ЧЧ:ММ:СС: /^\d{2}:\d{2}(:\d{2})?$/sSX

строгая валидация

  • Валидация даты в формате ГГГГ-ММ-ДД с проверкой корректности года, месяца и дня, но без проверки YYYY-02-29 в високосных годах (нужно доделать): PCRE

Форматы

  • Валидация IPv4 + IPv6: PCRE, link. В языках программирования есть готовый валидатор: PHP — filter_var(), NodeJS — net.isIP().
  • Захват адреса электронной почты (Email address) из текста: PCRE
  • Захват многострочных комментариев, где они НЕ могут быть вложены друг в друга (C-style), в 3 раза эффективнее, чем /\* .*? \*/: PCRE
  • Захват многострочных комментариев, где они могут быть вложены друг в друга (PostgreSql): PCRE
  • Base64: PCRE

Захват номера телефона РФ из текста

Включая номера, которые пытаются скрыть, используя разные разделители цифр.

PCRE

/
    (?<!\d) #boundary
    (  #1 код страны для РФ
          \+7 [^\d\n,;]{0,5}
      |  [78] [^\d\n,;]{0,5}
    )?
    (?<!\+)
    ([489][\dOО]{2})  #2 код города или код мобильного оператора для РФ (цифра, поддельная русская/англ. буква, похожая на ноль)
    ( (?:(?!\x20*[дД][оО]\x20*\d)  #не является диапазоном
         (?!\x20*р(?:уб)?[^а-я])  #не является денежной суммой
         [^\d\n,;]{0,5}
         [\dOО]
      ){7}
    )  #3 номер телефона для РФ 7 цифр
    (?!@[a-zA-Zа-яёА-ЯЁ\d]+\.)  #не является частью email
    (?!\x20*(?:руб|р\.|года))   #не является частью денежной суммы или указанием года
    (?!\d) #boundary
/gxs

Тестирование

# Invalid

79261234567@mail.ru
79261234567@почта.москва

+7926123456
+7 926123456
+7 926 123456
+7(926)123456

+9261234567

# Valid

## РФ fake
9261234567
79261234567
8 916 123 тире 45 тире 67
8_916_123_45_67

## РФ regular
++79261234567
+79261234567
+7 9261234567

+7 926 1234567
+7 968 123-45-67

+7(965)123-45-67 (доб. 318)
+7 965 123 45 67 #221
+7 965 123 45 67+221
+7 (495) 361-999-1
+7 (83166) 1-23-45
+7 831 66 1-23-45

## РФ local:
89261234567
8(965)1234567     c 10 до 24
8(965)123 45 67  (с 11.00 до 20.00)
8 965 66-38-5-85 (с 12:00 до 18:00)
8-965-663-85-85   (from 10am to 18pm)
8 (495) 361-999-1 (from 8 AM to 9 PM)
8 8316 123 4 56

## UAE: 
+971 2 4567890
+971 (0)2 4567890
+971 4 123 45 67
+971-4-1234567 
+971-50-1234567
+971-50-123-45-67

## Germany:
+49 511 4735138
+49 511 473-51-38
+49(511)473-51-38
+49 (511) 473-51-38

## Argentina
+54 9 2982 123456

## Moldova
+373 68 007777
+373 68 007777

HTML

  • Захват xml и html сущностей: PCRE, JS (strict); PCRE (non strict). См. так же список именованных сущностей в JSON.
  • Захват заданных html тегов с учётом их парности без вложенных таких же тегов: PCRE, JS
  • Захват заданных html тегов с учётом их парности и вложенности друг в друга (рекурсивно): PCRE, JS
  • Вставляет теги </li> там, где они пропущены (чинит некорректную вложенность тегов <li>): PCRE

Обработка естественного языка

  • Удаление начальных и конечных пробелов: PCRE
  • Валидация слова на английском языке во множественном числе: PCRE
  • Валидация ФИО на русском или английском языке: PCRE
  • Выделение слов и чисел из текста PCRE
  • Поиск дубликатов в списке через запятую PCRE

SQL

  • Детектирование SQL на модификацию данных: PCRE

PostgreSQL v10+

  • Разбиение SQL на несколько запросов по символу ;: PCRE

Захват квотированной строки (PCRE):

(?>     
        '(?>[^']+|'')*'                    #string constants
    |   \b[Ee]'(?>[^\\']+|''|\\.)*'        #string constants with C-style escapes
    |   (?<stringDollarTag>\$[a-zA-Z\d_]*\$) #dollar-quoted string
            [^$]*+  #speed improves
            .*?
        \k<stringDollarTag>
)

Захват квотированного названия объекта БД (PCRE):

"(?>[^"]+|"")*"

Захват комментариев (PCRE):

(?>
    #singe-line comment
    (?<singeLineComment>-- [^\r\n]*+)
  |
    #multi-line comment
    (?<MutilineComment>
        /\*
          [^*/]*+
          (?> [^*/]++
            | \*[^/]
            | /[^*]
            | (?&MutilineComment) #recursive
          )*+
        \*/
    )
)

MySQL v8+

Захват квотированной строки (PCRE):

(?>"(?>[^\\"]+|""|\\.)*"|'(?>[^\\']+|''|\\.)*')

Захват квотированного названия объекта БД (PCRE):

`(?>[^\\`]+|``|\\.)*`

Захват комментариев (PCRE):

(?>
    #singe-line comment
    (?<singeLineComment>-- (?=\s) [^\r\n]*+)
  |
    #multi-line comment by Jeffrey Friedl (fastest)
    (?<multiLineComment>
        /\*
          [^*]* \*+
          (?:[^*/][^*]*\*+)*
        /
    )
)

ClickHouse v1+

Захват квотированной строки (PCRE):

'(?>[^\\']+|''|\\.)*'

Захват квотированного названия объекта БД (PCRE):

(?>"(?>[^\\"]+|""|\\.)*"|`(?>[^\\`]+|``|\\.)*`)

Захват комментариев (PCRE):

(?>
    #singe-line comment
    -- [^\r\n]*+
  |
    #multi-line comment by Jeffrey Friedl (fastest)
    /\*
      [^*]* \*+
      (?:[^*/][^*]*\*+)*
    /
)

Прочее

  • Валидация (неполная, но быстрая) регулярного выражения на диалект ECMA 262 (JavaScript), есть проверка на уникальность флагов: PCRE

Валидация качества пароля

Регулярное выражение: PCRE

Пароль должен соответствовать следующим требованиям:

  1. длина от 8 до 72 символов (72 символа — это ограничение алгоритма bf)
  2. допускаются только цифры, английские буквы и знаки пунктуации
  3. содержит хотябы одну цифру (0-9)
  4. содержит хотябы одну английскую прописную букву (A-Z)
  5. содержит хотябы одну английскую строчную букву (a-z)
  6. содержит хотябы один знак пунктуации: !"#$%&'()*+,-./:;<=>?@[\]^_``{|}~
  7. не имеют 6 и более подряд совпадающих символов типа "zzzzzz", "000000"
  8. не имеет "плохих" последовательностей типа "123456", "abcdef", "qwerty"

Парсинг CSV

  • Захват только непустых значений колонок: PCRE
  • Как распарсить CSV строку в таблицу? PCRE, PostgreSQL

Детектирование бинарных данных

Ищем до первого найденного управляющего символа по регулярному выражению /[\x00-\x1f](?<![\x08\x09\x0c\x0a\x0d])/ (одинаково в диалектах PCRE и JS)

JSON не должен определяться как бинарный, поэтому исключаем все специальные символы по спецификации:

  • \b represents the backspace character U+0008
  • \t represents the character tabulation character U+0009
  • \f represents the form feed character U+000C
  • \n represents the line feed character U+000A
  • \r represents the carriage return character U+000D

Ссылки по теме

  1. https://github.com/aloisdg/awesome-regex

About

The best regular expression patterns collection you have ever seen. Коллекция регулярных выражений.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published