Regex 在字符串中查找以“分隔”分隔的重复单词/&引用;
假设以下向量:Regex 在字符串中查找以“分隔”分隔的重复单词/&引用;,regex,r,Regex,R,假设以下向量: x <- c("/default/img/irs/irs/irs/irs/irs/irs/irs/irs/irs/irs/irs/irs/IRS.html/", "something/repeat/repeat_this") 我总是可以str_split(x,“/”并在列表上迭代duplicated()函数,并使用if()语句,但这将是非常低效的 期望的结果应该是一个带有真或假(或1和0)的向量。我认为下面的内容对您有用。首先,strsplit()中的fixed=TRUE
x <- c("/default/img/irs/irs/irs/irs/irs/irs/irs/irs/irs/irs/irs/irs/IRS.html/", "something/repeat/repeat_this")
我总是可以str_split(x,“/”
并在列表上迭代duplicated()
函数,并使用if()
语句,但这将是非常低效的
期望的结果应该是一个带有真或假(或1和0)的向量。我认为下面的内容对您有用。首先,
strsplit()
中的fixed=TRUE
绕过正则表达式引擎,直接进行精确匹配,使函数更快。接下来,anyDuplicated()
返回一个长度为1的整数结果,如果没有找到重复项,该结果将为零,否则将大于零。因此,我们可以使用strsplit()
拆分字符串,并在结果上迭代anyDuplicated()
。然后我们可以将结果向量与零进行比较
vapply(strsplit(x, "/", fixed = TRUE), anyDuplicated, 1L) > 0L
# [1] TRUE FALSE
为了安全起见,您可能需要删除任何前导的/
,因为它将在strsplit()
的结果中产生一个空字符,并且在某些情况下可能会产生误导性的结果(例如,字符串以/
开头和irs//irs
或类似的情况在字符串后面出现)。您可以使用sub(“^/”,“,”,x)
删除前导正斜杠
总之,让您的strsplit()
想法更快的方法有:
- 使用
中的strsplit()
绕过正则表达式引擎fixed=TRUE
- 使用
,因为它会在找到一个匹配项后停止查找anyDuplicated()
- 使用
,因为我们知道结果类型和长度vapply()
grepl(x, pattern = "((.+)/).*(/\\2(/|$))", perl=T)
当(.+)
表示出现在斜杠前的单词本身(捕获组2)时,*
允许在两个相等的子字符串之间出现任意长度的字符、数字和空格(/\\2(/|$)
如果单词出现在一个斜杠之后,后跟另一个斜杠或字符串结尾($
),则匹配
对于提取,您可以如上所述使用strsplit()。为什么不在
strsplit
之后使用table
而不是duplicated
,并且只保留出现多次的单词(如lapply(strsplit(x,“/”),函数(y)table(y)[table(y)>1])
。@Cath运行table
两次可能会比较慢。此外,添加fixed=TRUE
将显著提高性能。所以,经过一个小小的修改,temp1]
@DavidArenburg,在你发表评论之前,我有点听到你在我的脑海里说这句话;-)嗯,这比我想象的要容易!这是一个好主意,但在第二个结果中它是真的,在那里它应该是假的。OP需要精确匹配。我认为这只是部分匹配。此外,sapply()
不是必需的grepl()
是通过x
矢量化的,所以grepl((.+)/(\\1)”,x,perl=TRUE)
就可以了。谢谢,我不知道grepl是矢量化的!为精确匹配Closer编辑了正则表达式,但对x不起作用。对,我将编辑上面的正则表达式,以便在以后重复时匹配
grepl(x, pattern = "((.+)/).*(/\\2(/|$))", perl=T)