是否可以编写一个返回所需结果的正则表达式?正则表达式通常是包容性的 - 找到匹配。我希望能够将正则表达式转换为相反的 - 断言没有匹配。这可能吗?如果是这样,怎么样?
http://zijab.blogspot.com/2008/09/finding-opposite-of-regular-expression.html声明您应该将正则表达式括在
中/^((?!^ MYREGEX ).)*$/
,但这似乎不起作用。如果我有正则表达式
/[a|b]./
,字符串“abc”返回false,我的正则表达式和zijab建议的反转,
/^((?!^[a|b].).)*$/
。是否有可能写一个正则表达式的反转,或者我的想法不正确?
答案 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]
(与a
或b
匹配)的相反表达式为[^ab]
(既不匹配a
也不匹配b
)。
但是你的表达越复杂,互补表达也就越复杂。一个例子:
您希望匹配文字foo
。除了包含foo
的字符串之外,其他任何内容都匹配的表达式必须与
foo
(^.{0,2}$
)或foo
(^([^f]..|f[^o].|fo[^o])$
)或foo
的字符串。这一切都可以起作用:
^[^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)?+.+
匹配bar
,foox
和xfoo
,但不匹配foo
(或空字符串)。
在其他方言中可能有可能,但是不能让它自己工作(如果第二场比赛失败,他们似乎更愿意回溯?)