我认为这会存在,但我似乎无法在任何地方找到它。
我有多个字符串,我想提取匹配的部分。 实际上我的字符串是目录,我需要选择写入文件的位置,这是在所有字符串中匹配的位置。例如,如果您有一个包含三个字符串的向量:
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 \”。我怎样才能提取这个?
所有帮助表示赞赏!
吕克
答案 0 :(得分:3)
strsplit
和intersect
使用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]
)是TRUE
中ok
值的前导数量;否则,没有共同的前缀,所以返回""
。
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\\"