【问题标题】:Perl regexp how to negate a partPerl正则表达式如何否定一部分
【发布时间】:2012-02-25 02:44:27
【问题描述】:

我必须分离

D= d1| d2|...|dn

F=f1|f2|...|fn

目前,我使用如下所示的 if 语句检查这两个正则表达式:

if (($text_to_search =~ $D) && ($text_to_search !~ $F))

我怎样才能否定 F?是否可以对整个析取项或 F 的每个析取项使用负环视?

我应该是这样的:

regexp = (d1)| (d2) | (d3)  ... (dn) | NOT (f1) | NOT (f2) | ... | Not (fn)

括号是否定模式所必需的,不仅是第一个单个字符,不是吗?

编辑: 例如 D 是:a|b|c|d,F 是:1|2|3

现在的行为应该是这样的:

input: "abc" --> accepted
input: "a" --> accepted
input: "abc1" --> Not accepted
input: "2" --> NOT accepted
input: "a2bc1" --> Not accepted
(input: "xyz999" --> does not match - shouldn't be accepted)

F-disjunct 应该是“当在输入序列中看到这个时不匹配”

【问题讨论】:

  • 您能否向我们展示一些示例输入和期望的行为?
  • 不清楚你想要什么。您是否希望具有与该 if 语句相同的功能,但只有一个条件/表达式?
  • FWIW,这个问题我很清楚,我只是不想回答。
  • 我想生成一个正则表达式,目前有两个通过说 NOT regexp F。要么在一个表达式中说以下分离不是“允许”,要么不允许每个模式(如“不是 1,不是 2,不是 3")

标签: regex perl negate


【解决方案1】:

是的,您可以使用负前瞻。使用您的符号,我们可以构造这样一个组合正则表达式的形状:

/(?!F)D/

虽然有细微差别。让我们考虑一个简单的例子。

my $patternD = '^(\d\d\d\d | \w\w)$';
my $patternF = 'AA | 12';

如您所见,patternD 匹配由 4 个数字或 2 个单词字符组成的字符串。 PatternF 匹配 AA12。所以下面的片段打印出我们所期望的。

my $str = '1121';
print "patternD matches\n" if $str =~ /$patternD/x; # patternD matches
print "patternF matches\n" if $str =~ /$patternF/x; # patternF matches

现在,让我们使用一种简单的方法创建一个组合的正则表达式。

my $combined = "(?!($patternF))$patternD";
print "Combined regex matches\n" if $str =~ /$combined/x; # Combined regex matches?!

糟糕,我们这里有误报! (请记住,当且仅当正则表达式 D 匹配而 F 不匹配时,我们的组合正则表达式才应该匹配,但事实并非如此)。为什么是这样?答案很简单。我们制作了我们的组合正则表达式,以便如果 D 在某个位置匹配,则 F 只能从同一位置匹配。在这种情况下,D 匹配 $str\d\d\d\d 替代项)的开头,其中 AA12 都不能匹配。不过,解决方案很简单。我们应该给 F 一些灵活性,在它之前添加.*。最终结果是:

 my $combined = "(?!.*($patternF))$patternD";

无论 D 匹配到哪里,F ​​仍然有机会匹配字符串中的任何位置。

这个例子表明你想要达到的效果肯定是可行的,但是你不能简单地将你的两个正则表达式混合在一起,你必须先仔细检查最终结果。

HTH

【讨论】:

    猜你喜欢
    • 2011-09-24
    • 1970-01-01
    • 2020-10-17
    • 2013-09-27
    • 1970-01-01
    • 2013-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多