假设以下载体:
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)的向量。
答案 0 :(得分:7)
其他解决方案,如果您只想检查您的模式
grepl(x, pattern = "((.+)/).*(/\\2(/|$))", perl=T)
其中(.+)
表示出现在斜杠之前的单词本身(捕获组2),.*
允许在两个相等的子串之间出现任意长度的字符,数字和空格。如果单词出现在斜杠后跟另一个斜杠或字符串结尾((/\\2(/|$))
),则$
匹配。
对于提取,您可以使用strsplit(),如上所述。
答案 1 :(得分:6)
我认为以下内容对你有用。首先,fixed = TRUE
中的strsplit()
会绕过正则表达式引擎并直接进行精确匹配,从而使函数更快。接下来,anyDuplicated()
返回一个长度为1的整数结果,如果没有找到重复项将为零,否则大于零。因此,我们可以使用strsplit()
拆分字符串,并在结果上迭代anyDuplicated()
。然后我们可以将得到的矢量与零进行比较。
vapply(strsplit(x, "/", fixed = TRUE), anyDuplicated, 1L) > 0L
# [1] TRUE FALSE
为了安全起见,您可能希望删除任何前导/
,因为它会在strsplit()
的结果中产生空字符,并且在某些情况下可能会产生误导性结果(例如字符串的情况)以/
开始,irs//irs
或类似字符串后面出现。您可以使用sub("^/", "", x)
删除前导斜杠。
总之,让strsplit()
想法更快的方法是:
fixed = TRUE
中使用strsplit()
来绕过正则表达式引擎anyDuplicated()
,因为它会停止查找找到一个匹配项vapply()
因为我们知道结果类型和长度是什么