在由" /"分隔的字符串中查找重复的单词;

时间:2016-02-23 14:37:56

标签: regex r

假设以下载体:

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)的向量。

2 个答案:

答案 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()因为我们知道结果类型和长度是什么