3

我必须分离

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-析取应该像“当在输入序列中看到这个时不匹配”

4

1 回答 1

2

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

/(?!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 只能从同一位置匹配。$str在这种情况下,D 匹配(\d\d\d\d替代项)的开头,其中既不匹配AA也不12匹配。不过,解决方案很简单。我们应该在 F.*之前添加一些灵活性。最终结果是:

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

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

这个例子表明你想要实现的目标肯定是可行的,但是你不能简单地将两个正则表达式混合在一起,你宁愿首先仔细检查最终结果。

高温高压

于 2012-02-02T14:49:38.163 回答