如何与正则表达式“逆向匹配”?


111

我正在使用RegexBuddy,但无论如何我还是很麻烦:

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

现在,我想进行逆向匹配...即,我要匹配有6个字母的字符串的行,但前提是这6个字母不是 Andrea时,我应该怎么做?


编辑:我将编写使用此正则表达式的程序,我尚不知道是否在python或php中,我首先要学习一些正则表达式:)有不同类型的行,我想使用正则表达式选择我感兴趣的类型。一旦我获得了这些行,就必须应用另一个过滤器,只是为了与已知值不匹配,我需要所有其他过滤器,而不是那个。(?!不需要)工作正常,谢谢。:-)

我希望这可以澄清问题:)


实际上,听起来您可能最好向我们提供有关您正在做的事情的更多信息,并查看是否有人可以提供替代解决方案。通常,尝试通过构造与每行匹配的正则表达式来解析整个文件是一条相当复杂的路线:)
Dan Dan

Answers:


70
(?!Andrea).{6}

假设您的regexp引擎支持负前瞻。

编辑:..或者您可能希望[A-Za-z]{6}代替.{6}

编辑(再次):请注意,先行查找和后向查找通常不是“逆向”正则表达式匹配的正确方法。正则表达式并不是为进行否定匹配而设置的,而是将其留给您使用它们的任何语言。


您需要添加@Vinko Vrsalovic使用的^,以便它与“ ndrea \ n”不匹配
bdukes

2
。默认情况下不匹配\ n(某些语言[例如Perl]允许您打开该行为,但默认情况下。匹配所有内容\ n)。

1
(此外,OP从未提到该字符串必须在行首出现)
Dan Dan

1
您对OP意味着什么?
安德里亚·安布

1
安德里亚:OP的意思是“原始海报”,所以,我指的是你:)
丹丹,

47

对于Python / Java,

^(.(?!(some text)))*$

http://www.lisnichenko.com/articles/javapython-inverse-regex.html


4
这行不通。您正在考虑脾气暴躁的令牌习语。但该点必须位于前行之后,而不是之前。看到这个问题。但是无论如何,这种方法对于这个任务来说是过大的。
艾伦·摩尔

不知道它是用哪种语言编写的,但在Sublime文本中却像灵符一样工作,以清理我的测试数据。谢谢!
马提亚斯·迪里克斯

1
@AlanMoore实际上,它几乎可以用于此用例。但是,如果some text启动该行,它将返回错误的结果。
Zenexer

2
@Zenexer,这就是我的意思。如果该点在先行之后,而不是之前,则说明效果很好。
艾伦·摩尔

这是一个解释更多的链接。我不明白为什么?!,而不仅仅是!
蒂莫

21

更新了艾伦·摩尔的反馈

在PCRE和类似的变体中,您实际上可以创建一个正则表达式来匹配不包含值的任何行:

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

这称为调和贪婪令牌。缺点是它的表现不佳。


1
这是长格式的脾气暴躁的代币。只需[\s\S]在第二个looka后面加上点(或,仅在JavaScript中有用),就不需要第一个:^(?:(?!Andrea).)*$
艾伦·摩尔

@AlanMoore不错!我找不到能像那样工作的既定模式,所以我想出了自己的模式。而不是让我回答您的问题,您应该自己提供。
Zenexer

没关系,已经有很多好的答案。而且,您应该自己发明这种习语,也应得到荣誉。干杯!
艾伦·摩尔

为什么建议使用[\S\s]?OP正在谈论匹配行,但不包含“ Andrea”一词。与检查整个字符串是否包含此单词无关。我想念什么吗?
x-yuri

@ x-yuri我认为你是对的。我可能回答了我最初访问此页面时遇到的问题,而忽略了差异。尽管(<10 kbps),我的连接还不足以立即更新答案
Zenexer

11

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

您可以使用预读。以python为例

import re

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

分解:

(?!Andrea)的意思是“如果接下来的6个字符不是“ Andrea”,则匹配”;如果是的话

\ w表示“文字字符”-字母数字字符。这等效于类[a-zA-Z0-9_]

\ w {6}恰好表示6个单词字符。

re.IGNORECASE表示您将排除“ Andrea”,“ andrea”,“ ANDREA” ...

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



5

如果要在RegexBuddy中执行此操作,可以使用两种方法来获取所有不匹配正则表达式的行的列表。

在“测试”面板上的工具栏上,将测试范围设置为“逐行”。当您执行此操作时,将在同一工具栏上的“全部列出”按钮下出现“列出所有不匹配的行”项目。(如果看不到“全部列出”按钮,请单击主工具栏中的“匹配”按钮。)

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


5

(?!在实践中很有用。尽管严格来说,展望不是数学上定义的正则表达式。

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

这是一个自动计算结果的程序。其结果是机器生成的,通常比手写一个要复杂得多。但是结果有效。


1

我只是想出了这种方法,该方法可能会占用大量硬件,但是可以正常工作:

您可以将所有与正则表达式匹配的字符替换为空字符串。

这是一个单行:

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

我之所以使用它,是因为我被迫使用非常复杂的正则表达式,并且无法弄清楚如何在合理的时间内转换它的每个部分。

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


-3

在perl中,您可以

process($ line)if($ line =〜!/ Andrea /);


4
该语法是错误的。我认为您的意思是process($ line),如果$ line!〜/ Andrea /
dland
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.