Причина, по которой ваше перевернутое регулярное выражение не работает, заключается в том, что '^
' внутри отрицательного взгляда:
/^((?!^[ab].).)*$/
^ # WRONG
Возможно, в vim все по-другому, но в каждом варианте регулярного выражения, с которым я знаком, каретка соответствует началу строки (или началу строки в многострочном режиме). Но я думаю, что это была просто опечатка в записи блога.
Вам также необходимо учитывать семантику используемого вами инструмента регулярных выражений. Например, в Perl это верно:
"abc" =~ /[ab]./
Но в Java это не так:
"abc".matches("[ab].")
Это потому, что регулярное выражение, переданное методу matches()
, неявно закреплено на обоих концах (то есть /^[ab].$/
).
Принимая более распространенную семантику Perl, /[ab]./
означает, что целевая строка содержит последовательность, состоящую из 'a' или 'b', за которой следует хотя бы один символ (разделитель строк). Другими словами, в ЛЮБОЙ точке условие ИСТИНА. Обратный результат этого утверждения в КАЖДОМ пункте - условие ЛОЖЬ. Это означает, что перед тем, как использовать каждый символ, вы выполняете отрицательный просмотр, чтобы подтвердить, что этот символ не является началом соответствующей последовательности:
(?![ab].).
И вы должны проверить каждый символ, поэтому регулярное выражение должно быть закреплено на обоих концах:
/^(?:(?![ab].).)*$/
Это общая идея, но я не думаю, что можно инвертировать каждый регулярное выражение - не тогда, когда исходные регулярные выражения могут включать в себя положительные и отрицательные обходные пути, неохотные и притяжательные квантификаторы, а кто-знает- что.