2013-02-25 135 views
16

我有一個data.frame包含文本列的文件名。我想返回沒有路徑或文件擴展名的文件名。通常,我的文件名已被編號,但不一定是。例如:正則表達式返回文件名,刪除路徑和文件擴展名

df<-data.frame(data=c("a","b"),fileNames=c("C:/a/bb/ccc/NAME1.ext","C:/a/bb/ccc/d D2/name2.ext")) 

我想回的

df<-data.frame(data=c("a","b"),fileNames=c("NAME","name")) 

等價,但我想不出華而不實的正則表達式與GSUB做到這一點。例如,我可以擺脫與擴展的(提供的文件名稱以數字結尾):

gsub('([0-9]).ext','',df[,"fileNames"]) 

雖然我一直在嘗試不同的模式(通過閱讀本網站上的正則表達式的幫助文件和類似的解決方案),我不能得到一個正則表達式來返回最後一個「/」和第一個「。」之間的文本。任何想法或轉發類似的問題,非常感謝!

我得到的最好的是:

gsub('*[[:graph:]_]/|*[[:graph:]_].ext','',df[,"fileNames"]) 

但這1)不擺脫所有領先的路徑中的字符和2)是依賴於特定的文件擴展名。

回答

33

或許這將讓你更接近你的解決方案:

library(tools) 
basename(file_path_sans_ext(df$fileNames)) 
# [1] "NAME1" "name2" 

file_path_sans_ext功能是從「工具」包(我相信通常帶有R),並且將提取的路徑達(但不包括)擴展名。然後basename函數將擺脫您的路徑信息。

或者,從file_path_sans_ext拍攝並稍作修改,你可以嘗試:

sub("(.*\\/)([^.]+)(\\.[[:alnum:]]+$)", "\\2", df$fileNames) 
# [1] "NAME1" "name2" 

在這裏,我已經「捕獲」的「文件名」變量的所有三個部分,因此,如果你想只文件路徑,您將"\\2"更改爲"\\1",如果您只需要文件擴展名,則可以將其更改爲"\\3"

+0

有趣的方法。對我來說,這種方法比正則表達式更清晰,這對我來說目前有點困惑。我會試一試。 – Docuemada 2013-02-25 18:52:11

+0

這很好,謝謝。這對我來說更有意義,但那可能是因爲我需要更多的正則表達式練習! – Docuemada 2013-02-25 19:10:53

+0

@Docuemada,沒問題。如圖所示,'file_path_sans_ext'是一個基本的正則表達式,因爲我懷疑'basename'是(但沒有檢查來驗證)。 – A5C1D2H2I1M1N2O1R2T1 2013-02-25 19:13:08

9

首先,要擺脫「領先路徑」,您可以使用basename。要刪除擴展,你可以在你的問題使用sub類似於你的描述:

filenames <- sub("\\.[[:alnum:]]+$", "", basename(as.character(df$fileNames))) 

請注意,您應該使用sub代替gsub這裏,因爲文件擴展名只能爲每個文件名出現一次。此外,您應該使用與點匹配的\\.,而不是匹配任何符號的.。最後,你應該追加$到這個模式,以確保你只有在文件名末尾的時候才刪除擴展名。

編輯:在阿南達Mahto的溶液所建議的功能file_path_sans_ext經由sub("([^.]+)\\.[[:alnum:]]+$", "\\1", x)代替去除擴展如上工作,文件名的非擴展部分被保留。在OP的案例中,我看不到兩種方法的具體優點或缺點。

+1

如果已將df $ fileNames作爲因子讀入,您可能需要在'df $ fileNames'周圍使用'as.character',如所提供的示例數據。 – A5C1D2H2I1M1N2O1R2T1 2013-02-25 18:40:05

+0

@Ananda編輯,謝謝。 – QkuCeHBH 2013-02-25 18:44:20

+0

謝謝,並感謝您解釋正則表達字符。這很好。對於這個例子,我使用了... as.character(df $ fileNames)。 – Docuemada 2013-02-25 19:04:48

相關問題