正则表达式 – 正确使用perl中负向前瞻表达式内的插入符号

前端之家收集整理的这篇文章主要介绍了正则表达式 – 正确使用perl中负向前瞻表达式内的插入符号前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_403_2@
我试图匹配任何不完全由大写字母或小写字母组成的单词,并且我有以下正则表达式:

if ($line =~ /(?!^[A-Z][A-Z]+(\s*)$)(?!^[a-z][a-z]+(\s*)$)/) {
    print $line;
}

下面的表达式应匹配所有大写字母的单词

(?!^[A-Z][A-Z]+(\s*)$)

这应该匹配所有小写字母的单词

(?!^[a-z][a-z]+(\s*)$)

我将两者结合起来并尝试将其与以下单词匹配:ASDSFSDF,asdfasdfasdf和asdasdfFFFdsfs.我注意到它匹配一切.只有当我将插入符号移动到括号外时,如下所示:

^(?![A-Z][A-Z]+(\s*)$)^(?![a-z][a-z]+(\s*)$)/)

我是否认为它只能加工asdasdfFFFdsfs.有人可以向我解释为什么我需要将运算符移到负前瞻表达式之外吗?我是regexp的新手,我很困惑.

谢谢.

解决方法

你陷入了多次否定和锚定的陷阱,而你所产生的正则表达并没有完全按照自己的意愿行事.假设我们只有简化的正则表达式/(?!^ [A-Z] $)/和字符串“1”.

在第一个位置(在1之前),测试断言.这里的^匹配,但[A-Z]没有.因此,^ [A-Z]失败.由于前瞻是否定的,整个模式都成功了.

现在让我们假设我们有字符串“A”.在第一个位置,测试断言.模式^ [A-Z] $匹配在这里.因为它是一个负前瞻,所以断言失败了.

然后,测试第二个位置(在A之后).断言已经过测试,但^在这里不匹配 – 因此否定断言使得模式成功!

因此,您的正则表达式与您想要的模式不匹配.您可以通过在断言之外锚定来抑制此行为:

/^(?![A-Z]$)/

在这种情况下.请注意,在您的情况下,最简单的解决方案是编写一个匹配您不想要的所有输入的正则表达式,并否定该结果:

print $line unless $line =~ /^(?:[A-Z]{2,}|[a-z]{2,})\s*$/;

(编辑:实际上TLP的第二个解决方案更简单,可能更有效)

@H_403_2@

猜你在找的正则表达式相关文章