2009-02-11 1 views
14

Qual è l'espressione regolare più corretta (regex) per un percorso di file UNIX?Qual è l'espressione regolare più corretta per un percorso di file UNIX?

Ad esempio, per rilevare qualcosa di simile:

/usr/lib/libgccpp.so.1.0.2 

E 'abbastanza facile fare un'espressione regolare che corrisponderà maggior parte dei file, ma qual è il migliore, tra cui uno in grado di rilevare sfuggito sequenze spazi bianchi, e caratteri insoliti che di solito non si trovano nei percorsi dei file su UNIX.

Inoltre, ci sono funzioni di libreria in diversi linguaggi di programmazione che forniscono un regex del percorso del file?

+0

"sfuggito sequenze spazi bianchi"? Usando quale sintassi di escape? I percorsi UNIX non hanno tali fughe. sh/ksh/bash hanno una sintassi di escape per lo più comune, gli URL ne hanno un'altra, Perl un'altra ancora. – Darron

risposta

13

Se non ti piacciono i falsi positivi per identificare i percorsi, devi solo assicurarti che il percorso non contenga un carattere NUL; tutto il resto è permesso (in particolare, / è il carattere nome-separatore). L'approccio migliore sarebbe quello di risolvere il percorso specificato utilizzando la funzione di file IO appropriata (ad esempio File.exists(), File.getCanonicalFile() in Java).

Risposta lunga:

Questo è sia operating system e file system dipendente. Ad esempio, i Wikipedia comparison of file systems note che oltre i limiti imposti dal file system,

MS-DOS, Microsoft Windows e OS/2 non consentire i caratteri \/: ? * " > < | e NUL in un file e directory nomi in tutti i filesystem. Unici e Linux non consentono i caratteri / e NUL nei nomi di file e directory su tutti i filesystem.

In Windows, il seguente reserved device names non sono inoltre ammessi come nomi di file:

CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, 
COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, 
LPT5, LPT6, LPT7, LPT8, LPT9 
+0

Additional: a causa della varietà tra i file system, ci sono metodi che ti forniscono le informazioni che ti servono. –

+0

@Robert: Grazie! Ho aggiornato la mia risposta di conseguenza. –

+0

Questi dispositivi speciali Win sono ancora peggio di quanto si pensi. Una volta ho ribattezzato un'intestazione C da const.h a con.h e il compilatore sembrava bloccarsi. Ci è voluto un po 'per capire che stava leggendo il file di intestazione dalla console perché Win ha ignorato l'estensione. Avvertenza: questo potrebbe essere stato DOS, è stato tanto tempo fa. – paxdiablo

3

io non sono sicuro di come comune un controllo regex per questo è tra i sistemi, ma la maggior parte dei linguaggi di programmazione (in particolare la croce piattaforma) fornire un controllo "file esiste" che terrà conto di questo tipo di cose

Per curiosità, dove vengono inseriti questi percorsi? Potresti controllarlo a un livello più alto fino al punto in cui non dovrai controllare i singoli pezzi del percorso? Ad esempio, utilizzando una finestra di dialogo selettore file?

11

La corretta espressione regolare per abbinare tutti i percorsi UNIX è: [^ \ 0] +

Cioè, uno o più caratteri che non sono una NUL.

+0

Si accetta '//' come percorso valido con questa espressione –

+5

e '//' è un percorso valido, con o senza '' s –

+5

non è una buona espressione regolare per abbinare percorso file valido –

8

Per gli altri che hanno risposto a questa domanda, è importante notare che alcune applicazioni richiedono una regex leggermente diversa, a seconda di come i caratteri di escape funzionano nel programma che si sta scrivendo.Se stavi scrivendo una shell, per esempio, e volevi avere un comando separato da spazi e altri caratteri speciali, dovresti modificare la tua espressione regolare per includere solo parole con caratteri speciali se questi caratteri sono sfuggiti.

Così, per esempio, un percorso valido sarebbe

 /usr/bin/program\ with\ space

al contrario di

 /usr/bin/program with space

che fare riferimento a "/ usr/bin/programma" con argomenti "con" e " spazio"

Un'espressione regolare per l'esempio di cui sopra potrebbe essere "([^ \ 0] \ | \\) *"

l'espressione regolare che ho state lavorando è (a capo separato per 'leggibilità'):

 "\(     # Either 
     [^\0 !$`&*()+] # A normal (non-special) character 
    \|     # Or 
     \\\(\ |\!|\$|\`|\&|\*|\(|\)|\+\) # An escaped special character 
    \)\+"     # Repeated >= 1 times 

che si traduce in

 
    "\([^\0 !$`&*()+]\|\\\(\ |\!|\$|\`|\&|\*|\(|\)|\+\)\)\+" 

Creare il proprio regex specifico dovrebbe essere relativamente semplice, pure.

+0

Ben fatto. Grazie! –

+1

In alternativa all'enumerazione di tutti i caratteri di escape, puoi semplicemente creare un gruppo che comprende l'escape seguito dalla classe di caratteri di escape '([^! $ \' & *() +] | (\\ [! $ \ '& *() +])) +' –

2
^(/)?([^/\0]+(/)?)+$ 

Questo accetterà ogni percorso che è legale in filesystem come extX, reiserfs.

Elimina solo i nomi dei percorsi contenenti le barre NUL o doppie (o più). Tutto il resto secondo le specifiche di Unix dovrebbe essere legale (sono sorpreso anche da questo risultato).

+1

le doppie barre sono perfettamente a posto nei percorsi unix, sia in POSIX che in pratica, quindi la tua regex non è corretta. l'unico carattere (o meglio, ottetto) non consentito nei nomi di percorso unix è \ 0 –