Построить отрицание произвольного регулярного выражения

mymedia

Преамбула

Регулярные выражения в программировании часто используются для валидации строк символов. Задача выяснить, удовлетворяет ли какая строка заданному выражению, довольно часто возникает при написании программ. Весьма распространены регулярки и во всяких конфигурационных файлах, настройках. Но если в тексте программы можно воспользоваться обычным оператором отрицания из языка программирования, в конфигах ситуация может быть сложнее. Допустим, нужно применить некоторую секцию конфигурации, только если строка с условием не начинается с некой подстроки, хотя синтаксис конфига позволяет только позитивную проверку (удовлетворяет ли строка регулярному выражению).

Итак, поскольку такая проблема слишком часто заводит меня в тупик, решил сформулировать её в более общем виде.

Постановка задачи

Пусть дано регулярное выражение R, содержащее любую, произвольную, заранее неизвестную комбинацию токенов, грамматически верную для движка PCRE. Требуется найти регулярное выражение !R, язык которого является дополнением для языка R. То есть любая строка, подходящая под R, не подходит под !R и наоборот.

Существует ли решение в общем виде? Если да, то предпочтительно включающее R в качестве подвыражения.

1 ответ

mymedia

Пусть R - любое валидное регулярное выражение, тогда регулярное выражение его дополняющее:

(?![\s\S]*R)\A[\s\S]*\Z

Объяснять тут особо нечего - захватываем ТОЛЬКО весь текст, если где-то внутри него нет соответствия шаблону R.

https://regex101.com/r/Kqd1qU/1

licensed under cc by-sa 3.0 with attribution.