正则表达式:多个负向先行断言

3

这是我的正则表达式模式:[Ss]ection\s\d+(?![a-zA-z])(?!</ref>)

例如,它应该匹配:section 5section 50

例如,它不应该匹配:section 5Asection 5</ref>section 5A</ref>section 50A

问题在于实际情况下,它错误地匹配了它们:http://regexr.com?33ien

不确定模式有什么问题...


3
“[Ss]ection\s\d++(?![a-zA-z])(?!</ref>)”能解决你的问题吗? - Pshemo
@Pshemo:\d++是什么意思? - jlordo
@jlordo.. \d++ 是一个贪婪量词 - Rohit Jain
@Pshemo:你能把那个评论发表为答案吗? - user1191027
面掌... 我自己经常发布这个链接。虽然我从来没有用过它,但这很有道理。 - jlordo
1
@Pshemo。你应该发布你的答案。它比现有的更好。 - Rohit Jain
3个回答

8
也许试试[Ss]ection\s\d++(?![a-zA-z])(?!</ref>)。 ++是占有型量词。这个量词与贪婪型量词类似,但它会阻止已匹配的字符串片段被后面的正则表达式所使用。
示例:
System.out.println("ababab".matches("(ab)++ab")); 
// prints false since last "ab" is possessed by (ab)++ 

2
匹配并没有错:在您的正则表达式中,您希望匹配"section "后面跟着一个或多个数字而不是跟着一些文本或者""。
这也适用于section 50A : section 5后面跟着0A,而这并不在您的负向先行断言中。
您可以尝试这样做:
[Ss]ection\s\d+(?![a-zA-Z0-9])(?!</ref>)

1
这个应该可以工作:

[Ss]ection\s\d+(?!\d)(?![a-zA-z])(?!</ref>)

我已经在Java正则表达式中负向先行断言的奇怪问题中解释了我们对于正则表达式前瞻的思考问题,这同样适用于此处。
这里的情况略有不同:当匹配器倾向于接受较短的匹配项以帮助整体匹配表达式时,负向先行断言确实会进行匹配。这就是为什么如果使用前瞻,有一个关于输入边界的概念非常重要:无论是单词边界、锚点$,还是关于后续文本的某些断言(在我的提议解决方案中不查看数字)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接