提取多个字符串的匹配部分

时间:2016-11-27 22:53:43

标签: r string

我认为这会存在,但我似乎无法在任何地方找到它。

我有多个字符串,我想提取匹配的部分。 实际上我的字符串是目录,我需要选择写入文件的位置,这是在所有字符串中匹配的位置。例如,如果您有一个包含三个字符串的向量:

select p.playerid
from players p
left join rosters r on p.playerid=r.playerid and r.leagueid=...
where r.playerid is null

...所有字符串中匹配的部分是“C:\ data \ files \”。我怎样才能提取这个?

所有帮助表示赞赏!

吕克

2 个答案:

答案 0 :(得分:3)

strsplitintersect使用Reduce递归重叠部分。然后,您可以通过paste - 。

将其重新组合在一起
paste(Reduce(intersect, strsplit(data.dir, "\\\\")), collapse="\\")
#[1] "C:\\data\\files"

正如@ g-grothendieck所指出的那样,在某些情况下会失败,例如:

data.dir <- c("C:\\a\\b\\c\\", "C:\\a\\X\\c\\") 

丑陋的黑客可能是这样的:

tail(
  Reduce(
    intersect,
    lapply(strsplit(data.dir, "\\\\"),
      function(x) sapply(1:length(x), function(y) paste(x[1:y], collapse="\\") ) 
    )
  ),
1)

......将处理这两种情况。

或者,如果您只有一个额外的目录级别,请使用dirname

unique(dirname(data.dir))
#[1] "C:/data/files"

答案 1 :(得分:2)

g包含data.dir[1]中连续反斜杠的字符位置。如果ok中所有元素的第一个TRUE字符相同,即g[i]的所有元素,则从此创建一个逻辑向量data.dir,其第i个元素为substr(data.dir, 1, g[i]) } 是相同的。如果ok[1]TRUE,则会有一个非零长度的公共前缀,其长度由g[k]的{​​{1}}个字符data.dir[1]所给出(等于k rle(ok)$lengths[1])是TRUEok值的前导数量;否则,没有共同的前缀,所以返回""

g <- gregexpr("\\", data.dir[1], fixed = TRUE)[[1]]
ok <- sapply(g, function(i) all(substr(data.dir[1], 1, i) == substr(data.dir, 1, i)))
if (ok[1]) substr(data.dir[1], 1, g[rle(ok)$lengths[1]]) else ""

对于问题中定义的data.dir,最后一行给出:

[1] "C:\\data\\files\\"