Регулярные выражения – это система обработки текста, основанная на специальной системе записи образцов. Проще говоря представляет программистам возможность легко обрабатывать и валидировать строки. Представляет имплементацию принципа DRY (Don’t Repeat Yourself), почти во всех поддерживаемых языках паттерн регулярных выражений не будет изменятся от слова совсем. Код написанный на backend и frontend приложениях будет идентичным, тем самым позволяя экономить время командам на реализацию одинаковых фич. Также стоит акцентировать внимание на том, что данный модуль идеально подходит для работы с большими строками или сложными строками т.к. даёт возможность решать задачи связанные с ними просто и быстро. Бывает за чашечкой чая на кухне или в команде вы можете услышать, что регулярные выражения довольно сложные в изучение, написание и чтение и вообще их придумали ужасные люди 😈. Но так ли это? Давайте разбираться Примечание: Данная статья актуальна для тех, кто считает регулярки сложными, непонятными и для тех, кто думает что базовые знания полностью хватает для работы. Далее представлены примеры на 6-х языках программирования определения российского номера телефона. Паттерн ^(?:8|\+7)[0-9]{10}$ C# new Regex(“^(?:8|\+7)[0-9]{10}$”).Match(“testdata”) PHP preg_match(“/^(?:8|\+7)[0-9]{10}$/”, “testdata”, match[]) Python re.match(r’^(?:8|\+7)[0-9]{10}$’,’testdata’) JS /^(?:8|\+7)[0-9]{10}$/.exec(“testdata”) Java “testdata”.matches(“^(?:8|\+7)[0-9]{10}$”) Dart RegExp(r"^(?:8|\+7)[0-9]{10}$").allMatches(“testdata”) В данном примере можно сразу заметить первую особенность Regex модуля, а именно паттерн условия будет полностью идентичным и вы можете легко поделится своим кодом с командой, которая пишет на другом языке программирования. А возможность быстро "шарить" кодовую базу между разными командами позволяет экономить время на разработку и реализацию фич. Впервые регулярные выражения возникли в научных работах по теории автоматов и теории формальных языков в середине 1950-х. Стефан Коул Клин признан человеком, который впервые ввёл понятие Регулярных Выражений. Принципы и идеи, заложенные в его работах, были практически реализованы Кеном Томпсоном и с его лёгкой руки проникли в язык Perl. По определению, Регулярные Выражения – это модуль вашего языка программирования, который используются для поиска и обработки текста. Язык Регулярных Выражений не является полноценным языком программирования, хотя, как и другие языки, имеет свой синтаксис и команды. Список довольно обширный вот лишь несколько из них: 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 Сопоставление входных данных по шаблону. Поиск и изменение входных данных по шаблону. Возвращение первого или всех результатов из входной строки. Возвращение вместе с результатом общего поиска, именованные и не только подстроки при поиске.  Замена символов, слов, фраз в входной строке после прохода. И самое главное, пиши один раз и используй везде. Поиск и замена кода по паттерну в 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 ≡ [^ ] – любой символ, кроме пробела Регулярное выражение Позитивный результат Негативный результат (Ч|ч)асы “Часы”, “часы” “39”, “Уаз”, “Час”, “чсы”, “асы” (Ч|ч)?асы “Часы”, “часы”, “асы” “39”, “Уаз”, “Час”, “чсы” .асы “Часы”, “уасы”, “#асы”, “Zасы”, “4асы” “39”, “Уаз”, “Час”, “чсы”, “асы” [0-9]+ “62”, “1”, “5123”, “632” “abs” a+b “ab”, “aab”, “aaaaaaab” “abs”, “b”, “cb”  [0-9]* “62”, “1”, “5123”, “632” “abs” a*b “ab”, “aab”, “aaaaaaab”, “b” “abs” \+7 “+7” “+1”, “++7”, “-7” ^\+7\d{10} “+79991112233”, “+712345678900” “+712345678” ^\+7\d{10}$ “+79991112233”  “+712345678900”, “+712345678” Кроме валидации значений в строке мы также можем указывать сколько символов должно проходить одно и тоже условие. Есть всего три возможности работать длиной условий: {3} – обязательное кол-во символов для условия  {3,5} – мин. и макс. кол-во символов для условия {3,} – обязательное мин. кол-во и неограниченное макс. кол-во Регулярное выражение Позитивный результат Негативный результат [0-9] {3} “632”, “777”, “891” “39”, “1”, “5123”, “abs” [0-9] {3,5} “632”, “12345”, “5123” “39”, “7”, “125123”, “abs” [0-9] {3,} “632”, “123456”, “5123” “39”, “0”, “abs” Примечание: Условие “[0-9]” можно заменить на сокращение “\d” Дальше будет немного сложно, готовьтесь. () – создание анонимной группы  (создание подстроки и выделение на неё памяти) (?‘nameGroup’) - (?<nameGroup>) – создание именованной строки (\k<nameGroup>) – служит для избавления паттерна от дубликат кода, то-есть если у вас есть именованная группа “nameGroup” с каким-то условием, вы можете не писать вторую группу в паттерне, а просто использовать данную директиву регулярных выражением указывая лишь название группы, которая была описана до. Тем самым, условие будет повторятся и вам не нужно описывать его заново. (?:) – выделение в логические скобки условия, без именование и создания подстроки (<=) – Исключает условия внутри скобок  и не включает его в выборку. (?!) – Проверяет условия внутри скобок  и не включает его в выборку. Однажды по работе нужно было парсить данные с QR кода, которые печатались на чеках при покупке/возврате разных товаров, услуг и т.д. Первая версия парсера была написана на бекенд части (C#). Кодовая база парсера была объёмом в ~150 строк кода, она не учитывала некоторые особенности разных фискальных регистраторов (устройства, которые печатают чеки и отправляют данные в ФНС). Для изменения данной функции требовалось внимательно смотреть, проверять каждую строчку кода. Позже вариантов стало так много и появилась необходимость использовать её на фронте для валидации. Соответственно, было решено переписать её, используя регулярные выражения для упрощение парсера и возможности легкого и быстрого переноса его на другой язык программирования. Цели:  Парсить входные значения для валидации по шаблону Брать необходимые поля дату и сумму покупки для дальнейшего использования в системе. Проверять что поле “n” равно всегда 1 (0 – возврат, 1 – покупка) Входные данные: t=20181125T142800&s=850.12&fn=8715000100011785&i=86841&fp=1440325305&n=1 Регулярное выражение на парсинг данных: ^t=(?<Date>[0-9-:T]+)&s=(?<Sum>[0-9]+(?:\.[0-9]{2})?)&fn=[0-9]+&i=[0-9]+&fp=[0-9]+&n=1$ Пример кода (C#): Пример кода на JS: Это вариант сделан через Exception-ы, но можно сделать через return false или return null. На выходе мы получаем получаем два значения: Date – поле обозначающее дату и время покупки (осталось только спарсить её и превратить в объект даты) Sum – сумма покупки Теперь давайте разберём паттерн поподробнее: ^ – обозначающая начало строки t=(?<Date>[0-9-:T]+) – обязательные символы  t=(далее любые символы (от 0 до 9 или - или : или T) в одном или более экземпляре) &s=(?<Sum>[0-9]+(?:\.[0-9]{2})?) – обязательные символы  &s= – обязательная последовательность символов & и s и = [0-9]+(символы от 0 до 9 одном или более экземпляре) (?:\.[0-9]{2})? $ – обозначающая конец строки &fn=[0-9]+ – обязательные символы &fn= и далее [0-9]+ -> (любое число от 0 до 9 в одном или более экземпляре) &i=[0-9]+ – обязательные символы &i= и далее [0-9]+ -> (любое число от 0 до 9 в одном или более экземпляре) &fp=[0-9]+ – обязательные символы &fp= и далее [0-9]+ -> (любое число от 0 до 9 в одном или более экземпляре) &n=1 – обязательные символы &n=1 Когда вам необходимо работать со всем алфавитом из латыни, достаточно просто написать [a-zA-Z]. Многие подумают что при работе с кириллицей хватает написать [а-яА-Я]. Вроде всё логично и всё хорошо, но в какой-то момент вы поймете, что у вас иногда она работает некорректно. Проблема заключается в том, что диапазон [а-я] не включает в себя букву “ё”, соответственно, вам необходимо изменить ваш паттерн с [а-яА-Я] на [а-яёА-ЯË], чтобы код учитывал специфичную букву в алфавите. Такая проблема есть не только в кириллице, также эта проблема актуальна для греческого, турецкого и ряда других языков. Будьте внимательны при написание паттерна, который должен использовать эти языки. global (g) - не прекращает поиск после нахождения первого соответствия. multi line (m) - ищет по строке включая перенос строки (^ начало строки, $ конец строки). insensitive (i) - производить поиск вне зависимости от регистра (a ≡ A) sticky (y) - поиск возвращает, кроме совпадения индекс с начала совпадения подвыборки (не поддерживается в IE) unicode (u) - поиск включает unicode символы (не поддерживается в IE) single line (s) - в этом режиме символ “.” включает в себя также перенос на новую строку (поддерживается в Chrome, Opera, Safari) 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. Пожалуйста, если у вас будут вопросы милости прошу в комментарии, где мы сможем с вами подискутировать. P.S. Программируйте это всё ещё классно) P.P.S. Привет всем кто пришёл сюда с mergeconf P.P.P.S. Спасибо Serge78rus за небольшое исправление по описанию операции +. → Замеры на разных языках → Онлайн regex-помощник со словарём всех доступных команд и поддержкой нескольких языков программирования. TeamLead