2008-10-02 1002 views
78

我使用的是RegexBuddy,但我无论如何都遇到了这个问题:\如何与regex“反向匹配”?

我正在逐行处理一个文件。我建立了一个“线条模型”来匹配我想要的。

现在我想要做的逆匹配...即我想匹配,其中有6个字母串线,但只有这六个字母安德烈,我应该怎么办那?


编辑:我会写一个使用此正则表达式的程序,我还不知道如果在Python或PHP中,我第一次做这个事情,了解一些正则表达式:)有不同类型的行,我想用正则表达式来选择我感兴趣的类型。一旦我得到了这些行,我必须应用其他过滤器只是为了不匹配已知的值,我需要所有其他的,而不是那。 (?!不想要的)工作得很好,谢谢。 :-)

我希望这个澄清的问题:)

+0

这实际上听起来像你可能会做得更好,给我们更多关于你在做什么的信息,并看看有人能提供一种替代解决方案。通常,尝试通过构建匹配每行的正则表达式来解析整个文件是一个相当复杂的路径:) – Dan 2008-10-02 20:33:22

回答

47
(?!Andrea).{6} 

假设你的正则表达式引擎支持的负面向前看符号..

编辑:..或者也许你宁愿在场所使用[A-Za-z]{6}.{6}

编辑(再次):请注意,lookaheads和lookbeheads通常不是正确的方式来“反转”正则表达式匹配。正则表达式并不是用来做负面匹配的,他们把它留给你使用它们的任何语言。

+0

您需要添加@Vinko Vrsalovic使用的^,以便它不匹配“ndrea \ n” – bdukes 2008-10-02 20:34:47

+2

。与默认情况下不匹配\ n(某些语言[例如Perl]允许您打开该行为,但默认情况下匹配所有内容但是\ n)。 – Dan 2008-10-02 20:36:37

+1

(另外,OP从未提到过线必须在线的开始处出现) – Dan 2008-10-02 20:37:11

5

Negative lookahead assertion

(?!Andrea) 

这不正是一个倒置的比赛,但它是你可以直接用正则表达式做的最好的。不是所有的平台都支持它们。

10

你在用什么语言?正则表达式实现的功能和语法对此很重要。

您可以使用预见。使用Python作为例子

import re 

not_andrea = re.compile('(?!Andrea)\w{6}', re.IGNORECASE) 

要打破下来:

(?!安德烈)手段 '匹配,如果未来6个字符不是 “安德烈”';如果是的话

\ w表示一个“单词字符” - 字母数字字符。这相当于类[a-zA-Z0-9_]

\ w {6}意味着正好6个单词字符。

re.IGNORECASE意味着你将排除“安德烈”,“安德烈”,“安德烈” ......

另一种方法是使用你的程序逻辑 - 使用不匹配安德烈所有线路,并把它们通过第二个正则表达式来检查6个字符。或者首先检查至少6个单词字符,然后检查它是否与Andrea不匹配。

-3

在Perl中,你可以做

过程($线),如果($线=〜/安德烈/!);

4

如果你想在RegexBuddy中做到这一点,有两种方法可以得到不匹配正则表达式的所有行的列表。

在测试面板的工具栏上,将测试范围设置为“逐行”。当你这样做时,列出所有没有匹配的行将显示在同一工具栏上的全部列表按钮下。 (如果您没有看到全部列表按钮,请单击主工具栏上的匹配按钮。)

在GREP面板上,您可以打开“基于行”和“反转结果”复选框以获取您正在扫描的文件中的不匹配行的列表。

3

(?!在实践中是有用的。 虽然严格来说,展望未来是正确的数学定义表达。

您可以手动编写反转正则表达式。

这里是a program自动计算结果。 它的结果是机器生成的,通常比手写的要复杂得多。 但结果起作用。

10

更新与反馈Alan Moore

在PCRE和类似的变种,实际上就可以创建符合不包含任何有价值的行正则表达式:

^(?:(?!Andrea).)*$ 

这就是所谓的tempered greedy token。缺点是它表现不佳。

0

我刚刚想出了这个方法,这可能是硬件密集的,但它的工作:

可以更换成空字符串匹配的正则表达式所有字符。

这是一个oneliner:

notMatched = re.sub(regex, "", string)

我用这个,因为我被迫使用一个非常复杂的正则表达式,无法弄清楚如何反转的每一个部分。

这将只返回字符串结果,不包含任何匹配对象!