Назад

Regex for lazy developers

Regex for lazy developers

Наш Team Lead, Илья Ермошин, делится с вами интересной и полезной информацией о регулярных выражениях. Все, что вы не знали и боялись спросить! ;) 

Основы. Что такое Regex?

Регулярные выражения – это система обработки текста, основанная на специальной системе записи образцов. Она дает программистам возможность легко обрабатывать и валидировать строки. Представляет имплементацию принципа DRY (Don’t Repeat Yourself), почти во всех поддерживаемых языках паттерн регулярных выражений не будет изменяться. Код, написанный на backend и frontend приложениях, будет идентичным, позволяя экономить время командам на реализацию одинаковых фич. Также стоит обратить внимание на то, что данный модуль идеально подходит для работы с большими строками или сложными строками, так даёт возможность решать задачи связанные с ними просто и быстро. 

Как это выглядит?

Примеры на 6-х языках программирования определения российского номера телефона.

Первая особенность Regex модуля — паттерн условия будет полностью идентичным.

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

Как появились Regex? 

Впервые регулярные выражения возникли в научных работах по теории автоматов и теории формальных языков в середине 1950-х. Стефан Коул Клин признан человеком, который впервые ввёл понятие Регулярных Выражений.
Принципы и идеи, заложенные в его работах, были практически реализованы Кеном Томпсоном и с его лёгкой руки проникли в язык Perl.

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

Язык Regex не является полноценным языком программирования, хотя, как и другие языки, имеет свой синтаксис и команды.

Какие языки программирования поддерживают Regex?

Список довольно обширный вот лишь несколько из них:

C, C#, C++, Cobol, Delphi, F#, Go, Groovy, Haskell, Java, JavaScript, Julia, Kotlin, MATLAB, Objective-C, PHP, Perl, Python, R, Ruby, Rust, Scala, Swift, Visual Basic, Visual Basic .NET

Возможности регулярных выражений

  • Сопоставление входных данных по шаблону.
  • Поиск и изменение входных данных по шаблону.
  • Возвращение первого или всех результатов из входной строки.
  • Возвращение вместе с результатом общего поиска, именованные и не только подстроки при поиске. 
  • Замена символов, слов, фраз в входной строке после прохода.
  • И самое главное, пиши один раз и используй везде.

Где пригодятся Regex?

  • Поиск и замена кода по паттерну в IDE (VS Code, Rider, CLion, VS)
  • Валидация строк на соответствие шаблону (file extension).
  • Валидация полей на фронте (e-mail, phone number and other).
  • Валидация request и response данных.
  • Валидация огромных строк с последующим получением необходимых кусков текста без больших затрат по времени.

Базовый синтаксис

  • ^ – начало строки (означает, что входная строка должна начинаться с последующего символа после этого. Не подходит, если вы не знаете первый символ входной строки)
  • $ – окончания строки (означает, что все условия до этого символа буду являться конечным результатом входной строки и после них ничего дальше нет. Не подходит, если вы хотите вернуть несколько результатов из входной строки)
  • * – означает, что предыдущее условие до данного символа может встречаться один или несколько раз или вовсе не будет (соответственно может повторятся)
  • + – означает, что предыдущее условие до данного символа должно встречаться один и более раз (соответственно, может повторятся)
  • [a-z] – перечисление допустимого символа в входной строке, то есть может быть любой буквой из латыни в нижнем регистре (a or b or c … or x or y or z)
  • [0-9] – перечисление допустимого символа в входной строке, то есть может быть любой буквой из латыни в нижнем регистре (1 or 2 or 3 … or 7 or 8 or 9)
  • . – один любой символ
  • \ – экранирование любого спец. символа
  • | – операция OR (означает, что должно выполнится условие слева или условия справа от этой операнды)

Упрощение синтаксиса

  • \d ≡ [0-9] – любой символ от 0 до 9
  • \D ≡ [^0-9] – любой символ, кроме чисел
  • \w ≡ [a-zA-Z0-9_] – любой символ латыни, все числа и _
  • \W ≡ [^a-zA-Z0-9_] – любой символ, кроме латинских символов, чисел и _
  • \s ≡ [ ] – исключительно пробел
  • \S ≡ [^ ] – любой символ, кроме пробела

Разбор базового синтаксиса

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

  • {3} – обязательное кол-во символов для условия 
  • {3,5} – мин. и макс. кол-во символов для условия
  • {3,} – обязательное мин. кол-во и неограниченное макс. кол-во

Длина условий

Условие “[0-9]” можно заменить на сокращение “\d”

Проблема работы с не латынью

Когда вам необходимо работать со всем алфавитом из латыни, достаточно просто написать [a-zA-Z]. Многие подумают, что при работе с кириллицей хватает написать [а-яА-Я]. Вроде всё логично и всё хорошо, но в какой-то момент вы поймете, что у вас иногда она работает некорректно. 
Проблема заключается в том, что диапазон [а-я] не включает в себя букву “ё”, соответственно, вам необходимо изменить ваш паттерн с [а-яА-Я] на [а-яёА-ЯË], чтобы код учитывал специфичную букву в алфавите. Такая проблема есть не только в кириллице, также эта проблема актуальна для греческого, турецкого и ряда других языков. Будьте внимательны при написание паттерна, который должен использовать эти языки.

Флаги regex в JS

  • global (g) - не прекращает поиск после нахождения первого соответствия.
  • multi line (m) - ищет по строке включая перенос строки (^ начало строки, $ конец строки).
  • insensitive (i) - производить поиск вне зависимости от регистра (a ≡ A)
  • sticky (y) - поиск возвращает, кроме совпадения индекс с начала совпадения подвыборки (не поддерживается в IE)
  • unicode (u) - поиск включает unicode символы (не поддерживается в IE)
  • single line (s) - в этом режиме символ “.” включает в себя также перенос на новую строку (поддерживается в Chrome, Opera, Safari)

Дополнительные настройки regex в C#

RegexOptions выставляется как дополнительный параметр в конструкторе Regex класса. Также его можно указывать в методах Match, Matches.

  • None - выставляется по дефолту.
  • IgnoreCase (\i) - проверяет без учёта регистра.
  • Multiline (\m) - работа со строкой где есть переносы \n.
  • ExplicitCapture (\n) - добавляет в результат только именованные группы.
  • Compiled (будет полезен лишь в static варианте, ускоряет регулярку, замедляет компиляцию).
  • Singleline (знак “.” будет обозначать любой символ кроме \n и игнорирует его при поиске)
  • IgnorePatternWhitespace (\x) . (вырезает все пробелы, исключения в конструкциях[],{})
  • RightToLeft - поиск справа налево.
  • ECMAScript (JS like версия, но стиль группировки как в .NET).
  • CultureInvariant (сравнивает игнорирую раскладку клавиатуры).

Хорошие практики и советы по оптимизации

  • Чем меньше группировок, тем быстрее скорость выполнения. Cтарайтесь их избегать, если они вам не нужны.
  • Используя сокращения (\d, \w и другие), будьте уверены, что они полностью соответствуют вашим условиям поиска.
  • Если вы часто используете регулярные выражения, создайте его один раз глобально, тем самым снизив кол-во дубликат кода.
  • Почти везде есть возможность компиляции регулярных выражений, которая зачастую оптимизирует ваши выражения и ускоряет их выполнения. Но используйте их после проверки, это ускорит работу вашего кода.
  • Старайтесь уменьшить количество экранирования (\), данный функционал замедляет скорость выполнения во многих языках программирования.
  • У регулярных выражений есть поддержка utf кода символов. В некоторых моменты это позволит улучшить производительность, но уменьшит читаемость. Если решитесь их использовать, будьте уверены, что команда одобрит ваше решение и оно того стоит.

Регулярные выражения лишь хотят казаться сложными, но на самом деле возможности, которые они предоставляют, дают массу преимуществ и позволяют упростить и ускорить работу всем от Junior-а до Senior/Lead-a. 

Программируйте, это классно!