R regex编译器在给定regex上的工作方式不同

问题描述 投票:1回答:1

我正在努力完善this答案;并发现以下给出的正则表达式在R中无法正常工作(按其含义)。

 +?on.*$

根据我对正则表达式的理解,上述正则表达式匹配:

懒惰地间隔一或多次,然后是on,然后是所有内容(换行符除外),直到最后。

INPUT:

Posted by ondrej on 29 Feb 2020.
Posted by ona'je on 29 Feb 2020.

输出(根据我的说法,如果测试字符串中的上述正则表达式模式替换为“”)

Posted by
Posted by 

并且当我尝试在python (implementation here)javascriptjava (implementation here)中进行测试时;我得到了预期的结果。

const myString = "Posted by ondrej on 29 Feb 2020.\nPosted by ona'je on";

console.log(myString.replace( new RegExp(" +?on.*$","gm"),""));

另一方面,如果我试图在R (implementation here)中实现相同的正则表达式;我得到的结果是

Posted by ondrej
Posted by ona'je

这是意外的。

疑问

我以为R的正则表达式解析器可能工作方式不同(也许从右到左)。我阅读了有关R中正则表达式工作方式的文档,但发现与上述正则表达式的其他语言没有什么不同。我可能在这里错过了一些东西。我对R并不熟悉,但是就我的正则表达式知识而言;我相信上述正则表达式应该对每个标准正则表达式引擎都适用,因为它可以在javajavascriptpython(也可能在pcre中)工作(据我所知)。我的问题是为什么上述正则表达式在R中的工作方式不同?

javascript java python r regex
1个回答
1
投票

[看起来像TRE regex engine(默认用于基R regex函数),基于Henry Spencer于1986年最初编写的regex库,如果正则表达式中的第一个模式,则匹配字符串末尾的最短匹配项以惰性量词开始,以$锚点结束。

比较these cases

sub(" +?on.*$", "", Data)  # "Posted by ondrej" "Posted by ona'je"
sub(" +?on.*", "", Data)   # "Posted bydrej on 29 Feb 2020." "Posted bya'je on 29feb 2020"
sub(" +?on(.*)", "", Data) # as expected
sub(" +on.*", "", Data)    # as expected

发生了什么事?

  • 第一种情况为sub(" +?on.*$", "", Data),第一个模式将所有量词的贪婪程度设置为正则表达式中的相同级别。因此,第二个量词* 将被设置为惰性,即使在没有第一个空格用惰性量词?进行量化后,也没有+?。它是一个已知的TRE“错误”,在基于Henry Spencer的regexl库的其他一些regex引擎中也存在。

  • 第二个sub(" +?on.*", "", Data)的匹配方式与写为" +?on.*?"的方式相同(同样,由于第一个模式将贪婪级别设置为在该级别上是懒惰的),并且would only match大于或等于1个空格,然后on.*?在模式结尾时不匹配。

  • 第三者sub(" +?on(.*)", "", Data)产生了预期的结果,因为第二个量化模式.*位于另一个级别(深一个级别),并且其贪婪度不受 +?的影响另一个层面。因此,(.*)在此贪婪地匹配。

  • 第四位,sub(" +on.*", "", Data),由于第一个模式是贪婪的,所以产生了预期的结果,因此下一个量化模式的贪婪也是贪婪的。

© www.soinside.com 2019 - 2024. All rights reserved.