我在perl中使用正则表达式分组时遇到了麻烦。
当然这是一个更大的问题,但它与我正在处理的概念相同。提前感谢您的意见和建议。
下面的正则表达式应该只关心字符串的这一部分来做出决定。
doctor_who:EE
doctor_who:EP
doctor_who:前
但不是
doctor_who:EEH
代码:
$str = "doctor_who:ee123ABC451234.123"; #match
$str = "doctor_who:ep123YXZ451234.123"; #match
$str = "doctor_who:ex123451234.123"; #match
$str = "doctor_who:eeh1234LMNOP51234.123"; ##should not match
$str = "doctor_who:abc12341234.123"; ##should not match
$regex = "doctor_who:e[e|p|x]"; #--->problem, what to add/remove?
if ($str =~ m/$regex/){
print "match!";
}
else {
print "not matched\n";
}
答案 0 :(得分:2)
它具有负前瞻零宽度断言的微不足道。这假设您唯一不想具体匹配的是doctor_who:eeh*
:
/doctor_who:e(?!eh)[epx]/
在上面的例子中,只要我们匹配doctor_who:e
,我们就会在每场比赛中触发前瞻。如果绝对必要,我们可以通过仅使用它来获得效率,如@ikegami的评论所述:
/doctor_who:e(?:[px]|e(?!h))/
除非:
之后的第二个字符不是p
或x
,否则它将做的事情是推迟前瞻,然后仅当该字符为{{1}时}}
评论中显示的第二个示例根本没有使用外观:
e
答案 1 :(得分:1)
由于你没有在字符串的末尾匹配,我认为你需要两个正则表达式。
$regex = "doctor_who:e[epx]"; # match
$not_regex "doctor_who:e[epx][a-z]"; #-do not match
然后就这样做
if( $string =~ $regex and $string !~ $not_regex ){}
答案 2 :(得分:1)
你可以通过两种方式完成这两种方式。
使用字符类:
$regex = 'doctor_who:e[epx]';
使用替换:
$regex = 'doctor_who:e(e|p|x)';
这些提供了积极的匹配,但他们需要其他东西来拒绝eeh
匹配。
但是,eeh
仅匹配是拒绝吗?这是您提到的唯一一个,但是,您是否更喜欢更通用的内容,例如任何 a-z 字符? (例如)eec
怎么办?它应该匹配还是被拒绝?
从示例中,ee1
匹配。这是因为1
不是 h
还是因为它是一个数字?
对我来说,至少应该完全清楚最好,最简洁的正则表达式应该是什么,因为这些例子中存在一些漏洞。所以,这里有一些正则表达式基于我对你真正喜欢的假设。
因此,如果eeh
是唯一拒绝,请添加:
$regex .= '[^h]';
如果您想要更广泛的拒绝:
$regex .= '[^a-z]';
或者,或许,您只想匹配数字:
$regex .= '[0-9]';
附注:此答案已经过编辑,以反映以下评论