我对这两者之间的区别感到惊讶:
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来加快性能。
松散相关,我通常可以假设tclk
比pcre
快得多吗?似乎来自一些非正式的基准测试。
答案 0 :(得分:2)
使用R
引擎时strapply
计算出捕获组本身的位置。您可以通过告诉它有多少人注意到它来帮助它。当使用tcl引擎时,tcl函数(最终用C语言编写)定位捕获组,使其不同的代码执行工作计算差异。
关于速度strapplyc
是包中最快的函数,而gsubfn
和strapply
较慢。 strapplyc
在非常长的字符串上可能特别快,但是对于你必须在R和tcl之间反复来回的情况,这样做会有一些开销。
对于一个长字符串的示例,请尝试?strapplyc
末尾的一个字符串,其中提取了James Joyce一书中的所有单词Ulysses。在编写strapplyc
时,某些不涉及gsubfn软件包的替代方法在我的系统上使用该示例崩溃了R,但是strapplyc
能够处理它并快速完成。
如果速度非常重要,请注意分解字符串是昂贵的,所以如果你能找到一种不能做到这一点的方法,那么你就可以获得速度优势。例如,gregexpr
只返回位置,因此它实际上不必移动字符串的副本,我希望它会更快,前提是您的代码不必随后在后续步骤中提取字符串。
使用tcl只是利用现有R设施获得一些速度的简单方法。对我来说,gsubfn
,strapply
和strapplyc
的主要优势在于它们可以用来更轻松地表达某些操作。所涉及的正则表达式有时更简单(通常不需要零长度前瞻,即使在替代方案中也是如此)并且gsubfn
和strapply
具有更丰富的替换对象集(字符串,函数,列表和原型对象) 。使用proto对象,它们可以在连续匹配之间保持状态(例如用i替换每个字符串中的第i个匹配)。有关详情,请参阅随附的vignette和home page。