对于几个不同的正则表达式,我发现regex的可选部分和条件部分对于第一次匹配和随后的匹配具有不同的行为。这是使用python,但我发现它具有一般性。
下面两个类似的例子说明了这个问题:
第一个例子:
表达方式:
(?:\w. )?([^,.]*).*(\d{4}\w?)
案文:
王建民,刘晓明,钱建安。代理网络容忍拒绝服务攻击的实证研究。“USENIX安全专题讨论会议事录”,2002年。
王建民,刘晓明,钱建安。代理网络容忍拒绝服务攻击的实证研究。“USENIX安全专题讨论会议事录”,2002年。
比赛:
匹配1
火柴2
第二个例子:
表达方式:
((?:\w\. )?[^,.]*).*(\d{4}\w?)
案文:
王建民,刘晓明,钱建安。代理网络容忍拒绝服务攻击的实证研究。“USENIX安全专题讨论会议事录”,2002年。
王建民,刘晓明,钱建安。代理网络容忍拒绝服务攻击的实证研究。“USENIX安全专题讨论会议事录”,2002年。
比赛:
匹配1
火柴2
我遗漏了什么?
我希望这会表现得有点不同,我认为这场比赛是一致的。我认为它应该是什么(而且还不明白为什么不应该是这样):
示例1
匹配1
火柴2
示例2
匹配1
火柴2
发布于 2017-08-31 05:53:09
在第一个例子中,您期望第二行与“Wang Wang”匹配。<<例1>>清楚地表明这不是正在发生的事情。
在第一场比赛之后,它以‘2002’结束。-正则表达式试图匹配以\n\nR. wang Wang
开头的其余部分。在您的第一个regex中,第一个非捕获组与它不匹配,所以您的组1接管并匹配它,最后得到'\n\nR‘。
(?: # non-capturing group
\w. # word char, followed by 1 char, followed by space
)? # read 0 or 1 times
( # start group 1
[^,.]* # read anything that's not a comma or dot, 0 or more times
) # end group 1
.* # read anything
( # start group 2
\d{4} # until there's 4 digits
\w? # eventually followed by word char
) # end group 2
这同样适用于您的第二个正则表达式:即使在这里,非捕获组(?:\w\. )?
也不使用R.
,因为在首字母前面有一个点和一些换行符。
您本可以像这样解决这个问题:([A-Z]\.)\s([^.,]+).*(\d{4})
:参见例3
https://stackoverflow.com/questions/45973788
复制相似问题