2009-02-11 21 views
14

¿Cuál es la expresión regular más correcta (regex) para una ruta de archivo UNIX?¿Cuál es la expresión regular más correcta para una ruta de archivo UNIX?

Por ejemplo, para detectar algo como esto:

/usr/lib/libgccpp.so.1.0.2 

Es bastante fácil de hacer una expresión regular que coincide con la mayoría de los archivos, pero ¿cuál es la mejor, incluyendo una que puede detectar escapado secuencias de espacios en blanco, y caracteres inusuales que no suele encontrar en las rutas de archivos en UNIX.

Además, ¿hay funciones de biblioteca en varios lenguajes de programación diferentes que proporcionan una ruta de archivo regex?

+0

"escaparon secuencias de espacios en blanco"? ¿Usando qué sintaxis de escape? Las rutas UNIX no tienen tales escapes. sh/ksh/bash tiene una sintaxis de escape mayoritariamente común, las URL tienen otra, Perl otra más. – Darron

Respuesta

13

Si no le molestan los falsos positivos para identificar rutas, entonces solo necesita asegurarse de que la ruta no contenga un carácter NUL; todo lo demás está permitido (en particular, / es el carácter separador de nombre). El mejor enfoque sería resolver la ruta dada utilizando la función de archivo IO apropiada (por ejemplo, File.exists(), File.getCanonicalFile() en Java).

Respuesta larga:

Esto es a la vez operating system y file system dependiente. Por ejemplo, los Wikipedia comparison of file systems notas que además de los límites impuestos por el sistema de archivos,

MS-DOS, Microsoft Windows y OS/2 no permitir los caracteres \/: ? * " > < | y NUL en archivos y directorios nombres a través de todos sistemas de archivos. Unices y Linux no permiten los caracteres / y NUL en los nombres de archivos y directorios en todos los sistemas de archivos.

En Windows, la siguiente reserved device names tampoco están permitidas como nombres de archivo:

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

Adicional: debido a la variedad entre los sistemas de archivos, existen métodos que le brindan la información que necesita. –

+0

@Robert: ¡Gracias! He actualizado mi respuesta en consecuencia. –

+0

Los dispositivos especiales Win son incluso peores de lo que crees. Una vez renombré un encabezado C de const.h a con.h y el compilador pareció colgarse. Tomó un tiempo darse cuenta de que estaba leyendo el archivo de encabezado de la consola porque Win ignoró la extensión. Advertencia: esto pudo haber sido DOS, fue hace mucho tiempo. – paxdiablo

3

No estoy seguro de lo común que un cheque de expresiones regulares para esto es a través de sistemas, pero la mayoría de los lenguajes de programación (especialmente la cruz de plataforma) proporcionan una verificación de "archivo existe" que tendrá este tipo de cosas en cuenta

Por curiosidad, ¿dónde se están introduciendo estos caminos? ¿Podrías controlar eso a un grado mayor hasta el punto en que no tendrás que verificar las piezas individuales de la ruta? Por ejemplo, utilizando un cuadro de diálogo selector de archivos?

11

La expresión regular correcta para que coincida con todos los caminos de UNIX es: [^ \ 0] +

Es decir, uno o más caracteres que no son una NUL.

+0

Aceptaría '//' como ruta válida con esta expresión –

+5

y '//' es una ruta válida, con o sin ' –

+5

esta no es buena expresión regular para que coincida con la ruta de archivo válida –

8

Para los demás que hayan respondido a esta pregunta, es importante tener en cuenta que algunas aplicaciones requerirían una expresión regular ligeramente diferente, dependiendo de cómo funcionan los caracteres de escape en el programa que está escribiendo.Si estuvieras escribiendo un intérprete de comandos, por ejemplo, y quisieras tener un comando separado por espacios y otros caracteres especiales, tendrías que modificar tu expresión regular para incluir solo las palabras con caracteres especiales si esos caracteres están escapados.

Así, por ejemplo, una ruta válida sería

 /usr/bin/program\ with\ space

en contraposición a

 /usr/bin/program with space

que se referiría a "/ usr/bin/programa" con argumentos "con" y " espacio"

una expresión regular para el ejemplo anterior podría ser "([^ \ 0] \ | \\) *"

la expresión regular que he estado trabajando en es (nueva línea separada para la 'lectura'):

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

que se traduce en

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

La creación de su propia expresión regular específica debe ser relativamente simple, también.

+0

Bien hecho. ¡Gracias! –

+1

Como alternativa a enumerar todos los caracteres escapados, simplemente puede hacer un grupo que conste del escape seguido de la clase de caracteres escapados '([^! $ \' & *() +] | (\\ [! $ \ '& *() +])) +' –

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

Esto aceptará todos los caminos que es legal en los sistemas de ficheros tales como extX, reiserfs.

Descarta solo los nombres de ruta que contienen el NUL o barras dobles (o más). Todo lo demás según las especificaciones de Unix debería ser legal (estoy sorprendido con este resultado también).

+1

Las barras diagonales dobles están perfectamente bien en las rutas Unix, tanto en POSIX como en la práctica, por lo que su expresión regular es incorrecta. el único carácter (o más bien, octeto) no permitido en las rutas de acceso de Unix es \ 0 –

Cuestiones relacionadas