От переводчика
Это перевод небольшой заметки, написанной вчера Lea Verou, в ней предлагается интересная, хотя и не новая техника для решения повседневных задач.
Информация в статье касается ECMAScript, но может использоваться и в других RegExp Движках (хотя и есть вероятность, что там есть более подходящее решение).
Если примеры кажутся вам сложными, рекомендую играть с ними в консоли, по мере прочтения. И Заранее прощу прочтение за пугающее название.
Статья
Если вы какое-то время используете регулярные выражения, то наверняка вы сталкивались с разными вариантами следующих задач:
- Пересечение:«Что-то, что совпадает с шаблоном А и шаблоном Б»
Например: Пароль, минимум 6 символов, в котором хотя бы одна цифра, хотя бы одна буква, и хотя бы один специальный символ
- Исключение: «Я хочу что-то, что совпадает с шаблоном А, но не совпадает с шаблоном Б»
Например: Любое целое число, которое не делится на 50
- Отрицание: Все. Что не совпадает с шаблоном А
Например: Строка, которая не содержит в себе слово «Foo»
Несмотря на то, что в ECMAScript есть циркумфлекс (^), для исключения набора символов, у нас нету возможности, исключить что-то более сложное.
Кроме того, у нас и есть вертикальная черта (|) обозначающая «ИЛИ», но нас нету ничего, что обозначало бы «И», и ничего что обозначало бы «КРОМЕ» (Исключение). Можно проделать все эти действия с несложным набором символов, с помощью символьных классов, но с со сложными последовательностями такое не получится.
Тем не менее, мы можем имитировать все три операции, воспользовавшись тем, что опережающие проверки не захватывают символы и не сдвигают позицию поиска. Мы можем просто продолжить искать соответствие дальше, и они будут совпадать с нужной нам подстрокой, поскольку опережающие проверки не захватывает ничего…
Исключение
В качестве простого примера: выражение
Вот решение для задачи, предложенной выше:
Пересечение
Для пересечения (И), мы просто можем выстроить в цепочку несколько позитивных опережающих проверок, а последним шаблоном захватить нужную нам строку (Если оставить только опережающие проверки, то мы все равно получим верный ответ, но можем получить неверные соответствия). Например, решение для задачи с паролем, приведенной выше, будет таким:
Если вы хотите, чтобы ваши регулярные выражения работали в Internet Explorer 8 версии и ниже, важно знать об этой ошибке и изменить ваши регулярные выражения соответствнно
Отрицание
Отрицание — проше всего. Нам всего лишь нужно негативное опережающие условие и
Заключение
В этой технике присутствуют некоторые сложности. В основном это связано с тем, что захватывается в результате. (Убедитесь, что захватывающий шаблон вне опережающих проверок захватывают всю строку, которая вам нужна)
Steven Levithan копает еще глубже, и пытается имитировать операторы условия и атомарные группы. Прощай мозг.
Пара бонусных ссылок
Утилита , разбирающая регулярные выражения по частям и объясняющая их
JS библиотека, значительно облегчающая работу с регулярными выражениями и добавляющая им функционал.