Thanks to visit codestin.com
Credit goes to github.com

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

[email protected]
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