2013-02-25 15 views
16

Ho un data.frame che contiene una colonna di testo di nomi di file. Vorrei restituire il nome del file senza il percorso o l'estensione del file. In genere, i miei nomi di file sono stati numerati, ma non devono esserlo. Per esempio:Regex restituisce il nome del file, rimuove il percorso e l'estensione del file

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

Vorrei tornare l'equivalente di

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

ma io non riesco a capire l'espressione regolare chiazza di petrolio per fare questo con gsub. Ad esempio, posso eliminare l'estensione con (a condizione che il nome del file termina con un numero):

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

Anche se ho cercato vari modelli (con la lettura dei file di espressione regolare di aiuto e le soluzioni simili su questo sito), Non riesco a ottenere un'espressione regolare per restituire il testo tra l'ultimo "/" e il primo ".". I pensieri o gli inviti a domande simili sono molto apprezzati!

Il migliore che ho ottenuto è:

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

Ma 1) non si libera di tutti i personaggi principali del percorso e 2) è dipendente da un formato specifico.

risposta

33

Forse questo ti porterà più vicino alla soluzione:

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

La funzione file_path_sans_ext è dal pacchetto "strumenti" (che credo solito viene fornito con R), e che estrarre il percorso fino a (ma non incluso) l'estensione. La funzione basename eliminerà quindi le informazioni sul percorso.

O, per prendere da file_path_sans_ext e modificarlo un po ', si può provare:

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

qui, ho "catturare" tutte e tre le parti delle variabili "nomi di file", quindi se si voleva solo i percorsi dei file, si dovrebbe cambiare "\\2" a "\\1" e se si desidera solo le estensioni di file, si cambierà in "\\3".

+0

Approccio interessante. Per me, questo approccio è più chiaro rispetto alla regex, che al momento è un po 'confusa per me. Lo proverò. – Docuemada

+0

Questo ha funzionato bene, grazie. Ha più senso per me, ma probabilmente è perché ho bisogno di più pratica con regex! – Docuemada

+0

@Docuemada, nessun problema. Come mostrato, 'file_path_sans_ext' è un'espressione regolare di base, poiché sospetto che' basename' sia (ma non controllato per verificare). – A5C1D2H2I1M1N2O1R2T1

9

Prima di tutto, per eliminare il "percorso iniziale", è possibile utilizzare basename. Per rimuovere l'estensione, è possibile utilizzare sub simile alla descrizione della tua domanda:

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

nota che si dovrebbe usare sub invece di gsub qui, perché l'estensione del file può avvenire solo una volta per ogni nome di file. Inoltre, è necessario utilizzare \\. che corrisponde a un punto anziché a . che corrisponde a qualsiasi simbolo. Infine, devi aggiungere $ al pattern per assicurarti di rimuovere l'estensione solo se si trova alla fine del nome file.

Edit: la funzione file_path_sans_ext suggerito in soluzione di Ananda Mahto funziona tramite sub("([^.]+)\\.[[:alnum:]]+$", "\\1", x), cioè invece di rimuovere l'estensione come sopra, la parte non estensione del nome del file viene mantenuto. Non vedo alcun vantaggio o svantaggio specifico di entrambi i metodi nel caso dell'OP.

+1

Probabilmente è necessario utilizzare un 'as.character' attorno a' df $ fileNames' se è stato letto come fattore, come nei dati di esempio forniti. – A5C1D2H2I1M1N2O1R2T1

+0

@Ananda Modificato, grazie. – QkuCeHBH

+0

Grazie, e grazie per aver spiegato i personaggi delle espressioni regolari. Funziona bene Per questo esempio, ho usato ... as.character (df $ fileNames). – Docuemada

Problemi correlati