Регулярное выражение противоположно

Можно ли написать регулярное выражение, которое возвращает обратное значение желаемого результата? Регулярные выражения обычно include в себя – поиск матчей. Я хочу иметь возможность преобразовать регулярное выражение в его противоположность – утверждая, что совпадений нет. Это возможно? Если да, то как?

http://zijab.blogspot.com/2008/09/finding-opposite-of-regular-expression.html заявляет, что вы должны скопировать ваше регулярное выражение с помощью

/^((?!^ MYREGEX ).)*$/ 

, но это, похоже, не работает. Если у меня есть регулярное выражение

 /[a|b]./ 

, строка «abc» возвращает false как с моим регулярным выражением, так и с обратным предложением, предложенным zijab,

 /^((?!^[a|b].).)*$/ 

, Можно ли написать обратное выражение регулярного выражения, или я неправильно думаю?

Причина, по которой ваше инвертированное регулярное выражение не работает, происходит из-за « ^ » внутри негативного outlookа:

 /^((?!^[ab].).)*$/ ^ # WRONG 

Возможно, это отличается от vim, но в любом регулярном выражении, с которым я знаком, карет соответствует началу строки (или началу строки в многострочном режиме). Но я думаю, что это была опечатка в блоге.

Вам также необходимо принять во внимание семантику используемого инструмента регулярного выражения. Например, в Perl это верно:

 "abc" =~ /[ab]./ 

Но в Java это не так:

 "abc".matches("[ab].") 

Это связано с тем, что регулярное выражение, переданное методу /^[ab].$/ matches() неявно закреплено на обоих концах (например, /^[ab].$/ ).

Принимая более распространенную семантику Perl, /[ab]./ означает, что целевая строка содержит последовательность, состоящую из «a» или «b», за которой следует по крайней мере один символ (нестрочный разделитель). Другими словами, в ЛЮБОЙ точке условие TRUE. Обратное к этому утверждению: в КАЖДОЙ точке условие FALSE. Это означает, что перед тем, как вы будете потреблять каждый символ, вы выполняете отрицательный просмотр, чтобы подтвердить, что символ не является началом соответствующей последовательности:

 (?![ab].). 

И вы должны изучить каждого персонажа, поэтому регулярное выражение должно быть привязано с обоих концов:

 /^(?:(?![ab].).)*$/ 

Это общая идея, но я не думаю, что можно инвертировать каждое регулярное выражение, а не когда исходные регулярные выражения могут включать в себя положительные и отрицательные образы, неохотные и притяжательные кванторы, а кто-что знает.

Не могли бы вы просто проверить, нет ли совпадений? Я не знаю, какой язык вы используете, но как насчет этого псевдокода?

 if (!'Some String'.match(someRegularExpression)) // do something... 

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

 /^((?!REGULAR_EXPRESSION_HERE).)*$/ 

Вы можете инвертировать набор символов, записав a ^ в начале ( [^…] ). Таким образом, противоположное выражение [ab] (совпадающее с a или b ) равно [^ab] (не соответствует ни a ни b ).

Но чем сложнее ваше выражение, тем сложнее дополнительное дополнение. Пример:

Вы хотите соответствовать буквальному foo . Выражение, которое соответствует любому другому, кроме строки, содержащей foo должно соответствовать либо

  1. любая строка, длина которой меньше foo ( ^.{0,2}$ ), или
  2. любые три строки длинной строки, которые не являются foo ( ^([^f]..|f[^o].|fo[^o])$ ), или
  3. любая более длинная строка, которая не содержит foo .

Все это может сработать:

 ^[^fo]*(f+($|[^o]|o($|[^fo]*)))*$ 

Но обратите внимание: это относится только к foo .

Вы также можете сделать это (в python) с помощью re.split и расщепления на основе вашего регулярного выражения, возвращая тем самым все части, которые не соответствуют регулярному выражению, как найти обратное выражение регулярного выражения

В perl вы можете противостоять $string !~ /regex/; ,

С помощью grep вы можете использовать --invert-match или -v .

Java Regexps имеют интересный способ сделать это (можно проверить здесь ), где вы можете создать жадное необязательное соответствие для нужной строки, а затем сопоставить данные после нее. Если жадное совпадение терпит неудачу, оно необязательно, так что это не имеет значения, если он преуспевает, ему нужны дополнительные данные для соответствия второму выражению, и это терпит неудачу.

Он выглядит контр-интуитивным, но работает.

Например, (foo)?+.+ foox bar , foox и xfoo но не будет соответствовать foo (или пустой строке).

Это возможно в других диалектах, но не может заставить его работать самостоятельно (они кажутся более склонными к отступлению, если второе совпадение не удастся?)

  • \ d менее эффективен, чем
  • Регулярное выражение для строки, содержащей одно слово, но не другое
  • Регулярное выражение для пароля (не менее 2 цифр и один специальный символ и минимальная длина 8)
  • Как использовать регулярные выражения, как эффективно сопоставлять строки между двойными кавычками со встроенными двойными кавычками?
  • Regex, каждый символ без буквенно-цифровых символов, кроме пробела или двоеточия
  • Сопоставьте все, кроме указанных строк
  • Что такое регулярное выражение для MAC-адреса?
  • RegEx: присвоение значений между кавычками
  • Регулярное выражение для подсчета числа запятых в строке
  • Как отменить все регулярное выражение?
  • Как сопоставить несколько вхождений строки в строке с помощью reg ex
  • Давайте будем гением компьютера.