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

我正在逐行处理一个文件,我想做一个反向匹配。例如,我想匹配有六个字母的字符串的行,但是只有当这六个字母不是“ 安德莉亚”时才匹配。我该怎么做?

我正在使用 RegexBuddy,但仍然有问题。

365445 次浏览
(?!Andrea).{6}

假设您的 regexp 引擎支持负向前看..。

或者你可以用 [A-Za-z]{6}代替 .{6}

请注意,正向和后向通常不是“反转”正则表达式匹配的正确方法。Regexp 实际上并不是为负匹配而设置的; 它们将负匹配留给您使用它们的任何语言。

否定的前瞻性断言

(?!Andrea)

这并不完全是一个反向匹配,但是这是您直接使用正则表达式所能做到的最好结果。但并非所有平台都支持它们。

正则表达式实现的能力和语法很重要。

您可以使用 look-ahead,以 Python 为例,

import re


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

分析一下:

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

W 表示“单词字符”-字母数字字符,这等同于类[ a-zA-Z0-9 _ ]

W {6} 正好意味着六个单词字符。

Re.IGNORECASE 表示您将排除“ ANDREA”,“ ANDREA”,“ ANDREA”..。

另一种方法是使用程序逻辑——使用所有与 安德莉亚不匹配的行,并将它们放入第二个 regex 以检查6个字符。或者首先检查至少6个单词字符,然后检查它是否与 安德莉亚不匹配。

在 Perl 中,您可以:

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

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

在 Test 面板上的工具栏上,将测试范围设置为“逐行”。这样做时,“列出所有不匹配行”项将出现在同一工具栏上的“列出所有行”按钮下。(如果没有看到 ListAll 按钮,请单击主工具栏中的 Match 按钮。)

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

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

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

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

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

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

这就是所谓的 一种温和的贪婪的象征。缺点是它不能很好地执行。

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

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

这是一篇文章:

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

我使用它是因为我不得不使用一个非常复杂的正则表达式,而且不知道如何在合理的时间内反转它的每个部分。

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

如果您有可能对相反的正则表达式进行两次匹配,并将它们连接在一起,那么您可以使用两个捕获组来首先捕获正则表达式之前的所有内容

^((?!yourRegex).)*

然后捕捉正则表达式后面的所有内容

(?<=yourRegex).*

这适用于大多数正则表达式。我发现的一个问题是当我在结尾有一个像{2,4}这样的量词时。那你就得有点创意。