如何得到正则表达式的逆?

时间:2009-07-17 01:04:18

标签: regex regex-negation inverse

假设我有一个正则表达式,可以正常查找文本文件中的所有网址:

(http://)([a-zA-Z0-9\/\.])*

如果我想要的不是网址而是相反的 - 除了网址之外的所有其他文字 - 是否有一个简单的修改可以获得这个?

4 个答案:

答案 0 :(得分:7)

您可以使用空字符串搜索并替换与正则表达式匹配的所有内容,例如在Perl s/(http:\/\/)([a-zA-Z0-9\/\.])*//g

除了那些与正则表达式匹配的子串外,这将为您提供原始文本中的所有内容。

答案 1 :(得分:4)

如果出于某种原因需要仅使用正则表达式的解决方案,请尝试以下方法:

((?<=http://[a-zA-Z0-9\/\.#?/%]+(?=[^a-zA-Z0-9\/\.#?/%]))|\A(?!http://[a-zA-Z0-9\/\.#?/%])).+?((?=http://[a-zA-Z0-9\/\.#?/%])|\Z)

我稍微扩展了一些网址字符([a-zA-Z0-9\/\.#?/%])以包含一些重要字符,但这绝不是准确或详尽的。

正则表达式是一个怪物,所以我会尝试将其分解:

(?<=http://[a-zA-Z0-9\/\.#?/%]+(?=[^a-zA-Z0-9\/\.#?/%])

第一部分匹配URL的结尾。 http://[a-zA-Z0-9\/\.#?/%]+匹配URL本身,而(?=[^a-zA-Z0-9\/\.#?/%])断言URL必须后跟非URL字符,以便我们确定我们已经结束。使用前瞻,以便寻找非URL字符但不捕获。整个事情被包裹在一个后视(?<=...)中,以寻找它作为匹配的边界,再次没有捕获该部分。

我们还希望在文件开头匹配非URL。 \A(?!http://[a-zA-Z0-9\/\.#?/%])匹配文件的开头(\A),然后是否定前瞻,以确保文件开头没有潜伏的网址。 (这个URL检查比第一个更简单,因为我们只需要URL的开头,而不是整个。)

这两项检查都放在括号中,OR'和|字符一起放在括号中。之后,.+?匹配我们尝试捕获的字符串。

然后我们来((?=http://[a-zA-Z0-9\/\.#?/%])|\Z)。在这里,我们再次使用(?=http://[a-zA-Z0-9\/\.#?/%])检查网址的开头。文件的结尾也是一个非常好的迹象,表明我们已经到了匹配的末尾,因此我们也应该使用\Z来查找。与第一个大集团类似,我们将它们括在括号中并将OR两种可能性结合在一起。

|符号需要括号,因为它的优先级非常低,因此您必须明确说明OR的边界。

这个正则表达式在很大程度上依赖于零宽度断言(\A\Z锚点以及环视组)。在将其用于任何严重或永久性的事情之前,您应该始终了解正则表达式(否则您可能会遇到perl的情况),因此您可能需要查看Start of String and End of String AnchorsLookahead and Lookbehind Zero-Width Assertions

当然欢迎更正!

答案 2 :(得分:1)

如果我正确理解了这个问题,你可以使用搜索/替换...只是在表达式周围使用通配符,然后替换第一个和最后一个部分。

s/^(.*)(your regex here)(.*)$/$1$3/

答案 3 :(得分:0)

我不确定这是否会按照您的意图完成,但可能有所帮助: 无论你在括号[]中放置什么都将被匹配。如果你把^放在括号内,即[^ a-zA-Z0-9 /。]它将匹配所有内容,除了括号内的内容。

http://www.regular-expressions.info/