我必须解散
D= d1| d2|...|dn
和
F=f1|f2|...|fn
目前我用if语句检查这两个regexp,如下所示:
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应该是“当在输入序列中看到这个不匹配时”
答案 0 :(得分:2)
是的,您可以使用否定前瞻。使用您的符号我们可以构造这样一个组合正则表达式的形状:
/(?!F)D/
虽然有细微差别。让我们考虑一个简单的例子。
my $patternD = '^(\d\d\d\d | \w\w)$';
my $patternF = 'AA | 12';
如您所见,patternD匹配由4位数或2个字符组成的字符串。 PatternF匹配AA
或12
。因此,以下片段打印出我们期望的内容。
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
替代)的开头,AA
和12
都不匹配。但解决方案很简单。我们应该在它之前添加.*
给予F一些灵活性。最终结果是:
my $combined = "(?!.*($patternF))$patternD";
无论D匹配哪里,F仍然有机会匹配字符串中的任何位置。
这个例子说明你想要实现的目标绝对可行,但你不能简单地将两个正则表达式混合在一起,而是首先要仔细检查最终结果。
HTH