【问题标题】:How can I extract matched part of multiple strings?如何提取多个字符串的匹配部分?
【发布时间】:2017-04-11 14:49:23
【问题描述】:

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

data.dir <- c("C:\\data\\files\\subset1\\", "C:\\data\\files\\subset3\\", "C:\\data\\files\\subset3\\")

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

【问题讨论】:

  • 您是在寻找字符串中间的任意匹配还是只是在寻找前缀匹配?如果是后者,您是否正在寻找分隔匹配? (所展示的应用程序确实允许最后一个假设,尽管标题并未暗示该限制。)

标签: r string


【解决方案1】:

strsplitintersect 使用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)

...这将处理任何一种情况。


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

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

【讨论】:

    【解决方案2】:

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

    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\\"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-10
      • 1970-01-01
      • 2021-09-29
      • 2015-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多