3 回答
TA贡献1799条经验 获得超9个赞
我不确定是否将其视为错误,因为我认为这是基于R文档的预期行为。来自?strsplit:
应用于每个输入字符串的算法是
repeat {
if the string is empty
break.
if there is a match
add the string to the left of the match to the output.
remove the match and all to the left of it.
else
add the string to the output.
break.
}
请注意,这意味着,如果(非空)字符串的开头存在匹配项,则输出的第一个元素为““””,但是如果字符串的末尾存在匹配项,则输出为与删除匹配项相同。
问题在于,向前(和向后)断言的长度为零。因此,在这种情况下,例如:
FF <- "(?=funky)"
testString <- "take me to funky town"
gregexpr(FF,testString,perl=TRUE)
# [[1]]
# [1] 12
# attr(,"match.length")
# [1] 0
# attr(,"useBytes")
# [1] TRUE
strsplit(testString,FF,perl=TRUE)
# [[1]]
# [1] "take me to " "f" "unky town"
发生的情况是,孤独的超前(?=funky)位置在位置12处匹配。因此,第一个拆分包括直到位置11(匹配项的左侧)的字符串,并将其与匹配项一起从字符串中删除,但匹配项的长度为零。
现在剩下的字符串是funky town,并且前行在位置1处匹配。但是,没有什么要删除的,因为在匹配项的左侧没有任何内容,并且匹配项的长度为零。因此,算法陷入了无限循环。显然,R通过拆分单个字符来解决此问题,顺便说一下,这是strsplit使用空的正则表达式(当参数为ing时split="")所记录的行为。在此之后,剩下的字符串是unky town,由于没有匹配项,因此将作为最后一个拆分返回。
Lookbehinds没问题,因为每个匹配项都被拆分并从剩余的字符串中删除,因此算法永远不会卡住。
乍一看,这种行为看起来很奇怪。但是,否则,行为将违背前瞻零长度的假设。鉴于strsplit已记录了该算法,我相信这不符合错误的定义。
TA贡献1817条经验 获得超14个赞
基于Theodore Lytras对substr()行为的仔细说明,一种合理的解决方法是在待匹配的超前断言前面加上一个与任何单个字符匹配的肯定后向断言:
testString <- "take me to funky town"
FF2 <- "(?<=.)(?=funky)"
strsplit(testString, FF2, perl=TRUE)
# [[1]]
# [1] "take me to " "funky town"
TA贡献1111条经验 获得超0个赞
对我来说似乎是个虫子。具体来说,这似乎不仅仅与空格有关,而是任何孤独的超前行为(正数或负数):
FF <- "(?=funky)"
testString <- "take me to funky town"
strsplit(testString,FF,perl=TRUE)
# [[1]]
# [1] "take me to " "f" "unky town"
FF <- "(?=funky)"
testString <- "funky take me to funky funky town"
strsplit(testString,FF,perl=TRUE)
# [[1]]
# [1] "f" "unky take me to " "f" "unky "
# [5] "f" "unky town"
FF <- "(?!y)"
testString <- "xxxyxxxxxxx"
strsplit(testString,FF,perl=TRUE)
# [[1]]
# [1] "xxx" "y" "xxxxxxx"
如果给出一些要捕获的内容以及零宽度断言,则似乎可以正常工作,例如:
FF <- " (?=XX )"
testString <- "text XX text"
strsplit(testString,FF,perl=TRUE)
# [[1]]
# [1] "text" "XX text"
FF <- "(?= XX ) "
testString <- "text XX text"
strsplit(testString,FF,perl=TRUE)
# [[1]]
# [1] "text" "XX text"
也许类似的东西可以作为解决方法。
- 3 回答
- 0 关注
- 690 浏览
添加回答
举报