2016-11-27 74 views
3

我認爲這會存在,但我似乎無法在任何地方找到它。提取多個字符串匹配的部分

我有多個字符串,我想提取匹配的部分。 實際上,我的字符串是目錄,我需要選擇寫入文件的位置,這是與所有字符串匹配的位置。例如,如果你有三個字符串數組:

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

......在所有的字符串相匹配的部分是「C:\ DATA \文件\」。我怎樣才能提取這個?

所有幫助表示感謝!

呂克

+1

您是否正在尋找在字符串中間的任意匹配或者你只是尋找一個前綴匹配?如果是後者,你是否在尋找劃定的比賽? (所提出的申請確實允許最後的假設,儘管標題沒有提出這種限制。) – JWLM

回答

3

strsplitintersect重疊部分遞歸使用Reduce。然後你可以通過paste -ing把它重新拼回去。

paste(Reduce(intersect, strsplit(data.dir, "\\\\")), collapse="\\") 
#[1] "C:\\data\\files" 

正如@ G-格羅騰迪克指出,這將在一定的情況下,像失敗:

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]字符位置連續的反斜槓。如果data.dir中的所有元素的第一個g[i]字符是相同的,那麼創建第i個元素爲TRUE的邏輯向量ok,即substr(data.dir, 1, g[i])的所有元素都是相同的。如果ok[1]TRUE然後有一個非零的長度公共前綴,其長度由的data.dir[1]第一g[k]字符給出,其中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\\"