gsubfn:perl和tclk之间的区别?

时间:2014-03-01 02:54:09

标签: regex r

我对这两者之间的区别感到惊讶:

strapply(state.name, "^(?:Al|Ma)(.).*(.)$", simplify=rbind, FUN=c, perl=T)
     [,1] [,2] [,3]
[1,] "a"  "a"  ""  
[2,] "a"  "a"  ""  
[3,] "i"  "e"  ""  
[4,] "r"  "d"  ""  
[5,] "s"  "s"  ""  
strapply(state.name, "^(?:Al|Ma)(.).*(.)$", simplify=rbind, FUN=c)
     [,1] [,2]
[1,] "a"  "a" 
[2,] "a"  "a" 
[3,] "i"  "e" 
[4,] "r"  "d" 
[5,] "s"  "s" 

对此有明显的解释吗?显然不是一件大事,特别是从以下情况开始:

strapply(state.name, "^(?:Al|Ma)(.).*(.)$", simplify=rbind, FUN=c, perl=T, backref=-2)

迫使正确答案,但我想确保我理解引擎的差异。据推测,这与不同的反向检测策略有关?从小插图:

  

由于gsubfn使用可能耗时的试错法算法来自动确定反向引用的数量,因此即使要传递所有后向引用,也可以通过指定backref来加快性能。

松散相关,我通常可以假设tclkpcre快得多吗?似乎来自一些非正式的基准测试。

1 个答案:

答案 0 :(得分:2)

使用R引擎时strapply计算出捕获组本身的位置。您可以通过告诉它有多少人注意到它来帮助它。当使用tcl引擎时,tcl函数(最终用C语言编写)定位捕获组,使其不同的代码执行工作计算差异。

关于速度strapplyc是包中最快的函数,而gsubfnstrapply较慢。 strapplyc在非常长的字符串上可能特别快,但是对于你必须在R和tcl之间反复来回的情况,这样做会有一些开销。

对于一个长字符串的示例,请尝试?strapplyc末尾的一个字符串,其中提取了James Joyce一书中的所有单词Ulysses。在编写strapplyc时,某些不涉及gsubfn软件包的替代方法在我的系统上使用该示例崩溃了R,但是strapplyc能够处理它并快速完成。

如果速度非常重要,请注意分解字符串是昂贵的,所以如果你能找到一种不能做到这一点的方法,那么你就可以获得速度优势。例如,gregexpr只返回位置,因此它实际上不必移动字符串的副本,我希望它会更快,前提是您的代码不必随后在后续步骤中提取字符串。

使用tcl只是利用现有R设施获得一些速度的简单方法。对我来说,gsubfnstrapplystrapplyc的主要优势在于它们可以用来更轻松地表达某些操作。所涉及的正则表达式有时更简单(通常不需要零长度前瞻,即使在替代方案中也是如此)并且gsubfnstrapply具有更丰富的替换对象集(字符串,函数,列表和原型对象) 。使用proto对象,它们可以在连续匹配之间保持状态(例如用i替换每个字符串中的第i个匹配)。有关详情,请参阅随附的vignettehome page