我有多个字符串,我想提取匹配的部分。实际上,我的字符串是目录,我需要选择写入文件的位置,这是所有字符串中匹配的位置。例如,如果有一个包含三个字符串的向量:
data.dir <- c("C:\\data\\files\\subset1\\", "C:\\data\\files\\subset3\\", "C:\\data\\files\\subset3\\")
在所有字符串中匹配的...the部件是"C:\data\files\“。我怎么才能把这个提取出来?
发布于 2016-11-27 14:57:13
strsplit
和intersect
使用Reduce
递归地处理重叠部分。然后,您可以通过paste
-ing将其组合在一起。
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)
...which将处理这两种情况。
或者,如果只有一个额外的目录级别,则使用dirname
:
unique(dirname(data.dir))
#[1] "C:/data/files"
发布于 2016-11-27 16:28:46
g
包含data.dir[1]
中连续反斜杠的字符位置。由此创建一个逻辑向量ok
,如果data.dir
中所有元素的第一个g[i]
字符是相同的,即substr(data.dir, 1, g[i])
的所有元素都是相同的,那么它的第一个元素是data.dir
。如果ok[1]
是TRUE
,那么就有一个非零长度的公共前缀,它的长度由data.dir[1]
的第一个g[k]
字符指定,其中k
(等于rle(ok)$lengths[1]
)是ok
中TRUE
值的前导数;否则,没有公共前缀,所以返回""
。
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\\"
https://stackoverflow.com/questions/40834854
复制相似问题