正则表达式相反

时间:2009-05-12 02:29:35

标签: regex

是否可以编写一个返回所需结果的正则表达式?正则表达式通常是包容性的 - 找到匹配。我希望能够将正则表达式转换为相反的 - 断言没有匹配。这可能吗?如果是这样,怎么样?

http://zijab.blogspot.com/2008/09/finding-opposite-of-regular-expression.html声明您应该将正则表达式括在

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

,但这似乎不起作用。如果我有正则表达式

/[a|b]./

,字符串“abc”返回false,我的正则表达式和zijab建议的反转,

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

。是否有可能写一个正则表达式的反转,或者我的想法不正确?

7 个答案:

答案 0 :(得分:12)

难道你不能检查一下是否没有比赛?我不知道你使用的语言是什么,但这个伪代码怎么样?

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

如果您只能更改正则表达式,那么您从链接获得的正则表达式应该有效:

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

答案 1 :(得分:9)

你的倒置正则表达式无法正常工作的原因是由于负向前瞻中的“^”:

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

也许它在vim中有所不同,但在我熟悉的每种正则表达式中,插入符号匹配字符串的开头(或多行模式中的行的开头)。但我认为这只是博客文章中的一个错字。

您还需要考虑您正在使用的正则表达式工具的语义。例如,在Perl中,这是真的:

"abc" =~ /[ab]./

但在Java中,这不是:

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

那是因为传递给matches()方法的正则表达式隐含地锚定在两端(即/^[ab].$/)。

采用更常见的Perl语义,/[ab]./表示目标字符串包含由'a'或'b'组成的序列,后跟至少一个(非行分隔符)字符。换句话说,在任何时候,条件为TRUE。该语句的反转是,在每个点上条件为FALSE。这意味着,在使用每个字符之前,执行否定前瞻以确认该字符不是匹配序列的开头:

(?![ab].).

你必须检查每个字符,所以正则表达式必须固定在两端:

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

这是一般性的想法,但我不认为可以反转每个正则表达式 - 而不是当原始正则表达式包含正面和负面的外观,不情愿和占有量词,以及谁知道 - 什么。

答案 2 :(得分:6)

您可以通过在开头^写一个[^…]来反转字符集。因此,[ab](与ab匹配)的相反表达式为[^ab](既不匹配a也不匹配b)。

但是你的表达越复杂,互补表达也就越复杂。一个例子:

您希望匹配文字foo。除了包含foo的字符串之外,其他任何内容都匹配的表达式必须与

匹配
  1. 任何短于foo^.{0,2}$)或
  2. 的字符串
  3. 任何三个字符长的字符串,不是foo^([^f]..|f[^o].|fo[^o])$)或
  4. 任何不包含foo的字符串。
  5. 这一切都可以起作用:

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

    但请注意:这仅适用于foo

答案 3 :(得分:2)

您也可以使用re.split执行此操作(在python中),并根据正则表达式进行拆分,从而返回与正则表达式不匹配的所有部分how to find the converse of a regex

答案 4 :(得分:1)

在perl中,您可以与$string !~ /regex/;反对。

答案 5 :(得分:0)

使用grep,您可以使用--invert-match-v

答案 6 :(得分:0)

Java Regexp有一种有趣的方法(可以测试here),您可以在其中为所需的字符串创建一个贪婪的可选匹配项,然后匹配它之后的数据。如果贪婪的匹配失败,那么它是可选的,所以它并不重要,如果成功,它需要一些额外的数据来匹配第二个表达式,因此失败。

看起来有点反直觉,但有效。

例如(foo)?+.+匹配barfooxxfoo,但不匹配foo(或空字符串)。

在其他方言中可能有可能,但是不能让它自己工作(如果第二场比赛失败,他们似乎更愿意回溯?)