在捕获组中使用贪婪修饰符时出现异常行为

9

考虑以下命令:

text <- "abcdEEEEfg"

sub("c.+?E", "###", text)
# [1] "ab###EEEfg"                          <<< OKAY
sub("c(.+?)E", "###", text)
# [1] "ab###EEfg"                           <<< WEIRD
sub("c(.+?)E", "###", text, perl=T)
# [1] "ab###EEEfg"                          <<< OKAY  

第一个正则表达式恰好符合我的期望,基本上只匹配第一个E。第二个应该与第一个基本相同,因为我只是添加了一个捕获组(尽管我没有使用它),但由于某种原因它捕获了一个额外的E。即使如此,它也不完全贪婪(即如果它是贪婪的,它将捕获所有的E)。更奇怪的是,它实际上仍然匹配模式,即使sub结果表明.+?部分留下了EE,而这些已经不能被正则表达式的其余部分匹配了。这表明在计算匹配子表达式的长度时存在偏移问题,而不是实际匹配中的问题。
最后一个与之前完全相同,但是使用 PCRE 运行,可以得到预期的结果。
我是遗漏了什么还是这种行为未经记录/存在缺陷?

这似乎是 R 中的一个 bug。 - nneonneo
发布在 tre GitHub 页面上的一个错误报告。 - BrodieG
1个回答

2

R 使用版本为 0.8 的 libtre。为了更稳定,在使用时应该始终使用 perl = TRUE

请注意:

sub("c(.+?)E?", "###", text)

工作。


这是我一直以来做的事情,但某些东西没有使用perl = T标志实现(特别是regexec)。我的实际错误出现在尝试使用regexec(或更具体地说,依赖它的stringr中的str_match_all/等工具)时,我同样能通过在模式后添加.*来解决它,尽管对于sub示例显然无效。如果明天早上没有其他人有更多信息,我会把这个作为答案。你知道是否有更新库的计划吗?看起来0.8已经存在4年了。 - BrodieG
实际上,看起来 **TRE库已经更新**(搜索TRE)。 - BrodieG
我修正了我的答案以反映更新。看起来libtre的开发并没有继续进行。有几个问题仍未解决,其中之一是关于R的问题。我认为这应该被提升为一个错误报告给R开发团队。 - Christopher Louden
我将此提交给了R,但被告知应该提交到TRE。我也向laurikari提交了,尽管我怀疑你所提供的链接是同样的问题。 - BrodieG

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