2009-04-16 22 views
31

Sto cercando di creare un'espressione regolare che rilevi qualsiasi carattere che Windows non accetta come parte di un nome file (sono gli stessi per altri sistemi operativi? Non lo so, ad essere onesto).Regex per sostituire i caratteri che Windows non accetta in un nome file

Questi simboli sono:

 \/: * ? " |

Comunque, questo è quello che ho: [\\/:*?\"<>|]

Il tester sopra a http://gskinner.com/RegExr/ mostra questo per funzionare. Per la stringa Allo*ha, il simbolo * si illumina, segnalando che è stato trovato. Devo inserire Allo**ha tuttavia, solo il primo * si illuminerà. Quindi penso di aver bisogno di modificare questo regex per trovare tutte le apparenze dei personaggi citati, ma non ne sono sicuro.

Vedete, in Java, ho la fortuna di avere la funzione String.replaceAll(String regex, String replacement). La descrizione dice:

Sostituisce ogni sottostringa di questa stringa che corrisponde all'espressione regolare data con la sostituzione specificata.

Quindi, in altre parole, anche se la regex trova solo il primo e quindi interrompe la ricerca, questa funzione li troverà ancora tutti.

Per esempio: String.replaceAll("[\\/:*?\"<>|]","")

Tuttavia, non mi sento come posso correre questo rischio. Quindi qualcuno sa come posso estendere questo?

+0

-1 rendere questo un qeustion e dirci la lingua o il contesto che si sta utilizzando e io ti darò il tuo voto schiena – ojblass

+0

Vorrei anche sapere che lingua il tuo utilizzo. – Kredns

+3

Tieni presente che, poiché la tua espressione regolare ha il formato di una stringa letterale Java, devi eseguire il doppio escape dei backslash: "[\\\\ /: *? \" <> |] ". Il modo in cui l'hai avuto, stavi solo sfuggendo alla barra diretta (che non è necessaria, ma non è neanche un errore) –

risposta

14

regole filename Windows sono difficile. Stai solo grattando la superficie.

Per esempio qui ci sono alcune cose che non sono nomi di file validi, oltre alle chracters avete elencato:

        (yes, that's an empty string) 
. 
.a 
a. 
a         (that's a leading space) 
a         (or a trailing space) 
com 
prn.txt 
[anything over 240 characters] 
[any control characters] 
[any non-ASCII chracters that don't fit in the system codepage, 
if the filesystem is FAT32] 

Rimozione caratteri speciali in un unico sub regex come String.replaceAll() non è sufficiente; si può facilmente finire con qualcosa di non valido come una stringa vuota o "." o "". Sostituire qualcosa come "[^ A-Za-z0-9 _.] *" Con '_' sarebbe un primo passo migliore. Avrai comunque bisogno di un'elaborazione di livello superiore su qualsiasi piattaforma tu stia utilizzando.

+0

Le regole dei nomi di file di Windows sono davvero complicate. Nessuno (nemmeno Microsoft) ha scritto un insieme di regole completamente corretto. Nemmeno io. Ma posso dirti "." è legale (quella directory esiste sempre), e ".a" e "a". e com e> 240 caratteri ecc. possono essere creati sfuggendo perfettamente ai nomi dei nomi. –

+0

Bene "." (E "..") sono nomi di percorso legali, ma non è possibile utilizzarli come nomi di file, ovviamente! Come si "sfuggono" punti iniziali/finali e nomi di file riservati? Non riesco a vedere alcuna interfaccia pubblica che lo consenta; sia l'interfaccia utente che l'interfaccia IO del file rinominano i punti e non consentono il nome riservato. – bobince

+0

(È possibile creare i percorsi lunghi rinominandoli e spostandoli, ma causa l'impossibilità di Explorer e molte altre applicazioni quando si accede a essi, motivo per cui è indesiderabile.) – bobince

0

Si potrebbe provare a consentire solo le cose che si desidera siano in grado di immettere, ad esempio A-Z, a-z e 0-9.

+1

Non dimenticare il periodo solitario. –

+1

Oppure la vasta gamma di caratteri Unicode validi e caratteri estesi utilizzati in tutto il mondo. – McDowell

2

Per la cronologia, i sistemi conformi a POSIX (inclusi UNIX e Linux) supportano tutti i caratteri tranne il carattere nullo ('\0') e la barra di inoltro() nei nomi file. Caratteri speciali come spazio e asterisco devono essere sfuggiti sulla riga di comando in modo che non assumano i loro soliti ruoli.

0

Non è possibile eseguire questa operazione con una singola espressione regolare, poiché un regexp corrisponde sempre a una sottostringa se l'input. Si consideri la parola Alo*h*a, non esiste una sottostringa che contenga tutti i * s e nessun altro carattere. Quindi, se puoi usare la funzione replaceAll, devi solo seguirla.

BTW, il set di caratteri vietati è diverso in altri sistemi operativi.

+0

Non sono sicuro di capire cosa stai dicendo, ma puoi sicuramente abbinare nomi di file non validi con un'espressione regolare. – wilhelmtell

+0

Sì, ma non è possibile disinfettare i nomi di file non validi sostituendo una singola occorrenza di un'espressione regolare senza un sacco di danni collaterali – jpalecek

1

Java ha una funzione replaceAll, ma ogni linguaggio di programmazione ha un modo per fare qualcosa di simile. Perl, ad esempio, utilizza lo switch g per indicare una sostituzione globale. La funzione Python sub consente di specificare il numero di sostituzioni da apportare. Se, per qualche ragione, la tua lingua non ha avuto un equivalente, si può sempre fare qualcosa di simile:

while (filename.matches(bad_characters) 
    filename.replace(bad_characters, "") 
16

poiché nessuna risposta è stata sufficiente, l'ho fatto io stesso. Spero che questo aiuti;)

public static boolean validateFileName(String fileName) { 
    return fileName.matches("^[^.\\\\/:*?\"<>|]?[^\\\\/:*?\"<>|]*") 
    && getValidFileName(fileName).length()>0; 
} 

public static String getValidFileName(String fileName) { 
    String newFileName = fileName.replaceAll("^[.\\\\/:*?\"<>|]?[\\\\/:*?\"<>|]*", ""); 
    if(newFileName.length()==0) 
     throw new IllegalStateException(
       "File Name " + fileName + " results in a empty fileName!"); 
    return newFileName; 
} 
+4

Questo non rimuove tutti i caratteri non validi. Hai omesso personaggi speciali, ad esempio. –

+1

Non impedisce^questo carattere speciale corrispondente eccetto all'inizio del nome del file? Ho usato fileName.replace ("^ \\. +", "") .replaceAll ("[\\\\ /: *? \" <> |] "," ") –

+0

Se cerchi di utilizzare qualsiasi altro carattere quindi "" la regex nella risposta non andrà a buon fine.Il Regex di Oliver Bock funziona bene.Il – Markus

1

estraggo tutti i caratteri di parole e caratteri di spazio bianco dalla stringa originale e ho anche fare in modo che carattere di spazio non è presente alla fine della stringa. Ecco lo snippet di codice in java.

temp_string = original.replaceAll("[^\\w|\\s]", ""); 
final_string = temp_string.replaceAll("\\s$", ""); 

Penso di aver aiutato qualcuno.

2

Uso un'espressione regolare pura e semplice. Dò caratteri che possono accadere e attraverso la negazione di "^" cambio tutti gli altri come segno di tale. "_"

String fileName = someString.replaceAll ("[^ a-zA-Z0-9 \\. \\ -]", "_");

Ad esempio: Se non si desidera essere nell'espressione a "." quindi rimuovere il "\\".

String fileName = someString.replaceAll ("[^ a-zA-Z0-9 \\ -]", "_");

-1

Anche Windows non accetta "%" come nome file.

Se si sta costruendo un'espressione generale che potrebbe interessare file che verranno eventualmente spostati su altri sistemi operativi, suggerisco di inserire più caratteri che potrebbero avere problemi con essi.

Ad esempio, in Linux (molte distribuzioni che conosco), alcuni utenti potrebbero avere problemi con i file contenenti [b] &! ] [/ -() [/ b]. I simboli sono consentiti nei nomi dei file, ma potrebbero dover essere trattati in modo speciale dagli utenti e alcuni programmi hanno bug causati dalla loro esistenza.

+0

% in un nome di file funziona per me su Windows 7. – rhens

0

ho fatto uno molto metodo semplice che funziona per me per i casi più comuni:

// replace special characters that windows doesn't accept 
private String replaceSpecialCharacters(String string) { 
    return string.replaceAll("[\\*/\\\\!\\|:?<>]", "_") 
      .replaceAll("(%22)", "_"); 
} 

% 22 viene codificato se avete qoute (") nei nomi di file.

0

La richiesta regex/sintassi (JS):

.trim().replace(/[\\/:*?\"<>|]/g,"").substring(0,240); 

dove l'ultimo bit è facoltativo, utilizzare solo quando si desidera limitare la lunghezza a 240.

altre utili funzioni (JS):

.toUppperCase(); 
.toLowerCase(); 
.replace(/ /g,' ');  //normalising multiple spaces to one, add before substring. 
.includes("str");  //check if a string segment is included in the filename 
.split(".").slice(-1); //get extension, given the entire filename contains a . 
Problemi correlati