假设以下向量:
x <- c("/default/img/irs/irs/irs/irs/irs/irs/irs/irs/irs/irs/irs/irs/IRS.html/", "something/repeat/repeat_this")
我想检查一个由/
括起来的单词是否被重复(注意,/
可能在字符串的开始和结束中丢失)。我发现了下面的正则表达式here,但是(在我去掉特殊字符之后)我似乎无法修改它以适应我的情况:
grepl("\\b(\\S+?)\\1\\S*\\b", x, perl = TRUE)
# [1] TRUE TRUE
我总是可以str_split(x, "/")
并在列表上迭代duplicated()
函数,并使用if()
语句,但这将是非常低效率的。
期望的结果应该是带有TRUE或FALSE (或1和0)的向量。
发布于 2016-02-23 06:47:36
我想以下几点可能对你有用。首先,fixed = TRUE
在strsplit()
中绕过正则表达式引擎,直接进行精确匹配,从而使函数速度更快。接下来,anyDuplicated()
返回一个长度为一个整数的结果,如果没有找到重复项,它将是零,否则返回大于零的结果。因此,我们可以使用strsplit()
拆分字符串,并对结果迭代anyDuplicated()
。然后,我们可以比较得到的向量与零。
vapply(strsplit(x, "/", fixed = TRUE), anyDuplicated, 1L) > 0L
# [1] TRUE FALSE
为了安全起见,您可能希望删除任何前导/
,因为它将在strsplit()
的结果中生成一个空字符,并且在某些情况下可能会产生误导性结果(例如,字符串以/
和irs//irs
开头或类似的情况在字符串后面发生)。您可以使用sub("^/", "", x)
删除前导正斜杠。
总之,使您的strsplit()
想法更快的方法是:
fixed = TRUE
中使用strsplit()
绕过正则表达式引擎anyDuplicated()
,因为它不再照看它找到一个匹配的vapply()
,因为我们知道结果的类型和长度发布于 2016-02-24 09:25:22
其他解决方案--如果您只想检查您的模式
grepl(x, pattern = "((.+)/).*(/\\2(/|$))", perl=T)
如果(.+)
表示出现在斜杠前面的单词本身(捕获组2),则.*
允许在两个相等的子字符串之间出现任意长度的字符、数字和空格。然后,如果该单词发生在斜杠之后,然后是另一个斜杠或字符串的末尾( (/\\2(/|$))
),则匹配。
对于提取,您可以使用上面详细阐述的strsplit()。
https://stackoverflow.com/questions/35580382
复制相似问题