Expresión regular para un nombre de archivo válido

Ya hice una pregunta en StackOverflow acerca de esto, pero nada ayudó mucho en mi caso.

Quiero restringir al usuario para que proporcione un nombre de archivo que debe contener solo caracteres alfanuméricos, - , _ y el espacio.

No soy bueno en expresiones regulares y hasta ahora se me ocurrió esto ^[a-zA-Z0-9.-_]$ . ¿Puede alguien ayudarme?

Esta es la expresión correcta:

 string regex = @"^[\w\-. ]+$"; 

\w es equivalente a [0-9a-zA-Z_] .

Para validar un nombre de archivo sugeriría usar la función proporcionada por C # en lugar de expresiones regulares

 if (filename.IndexOfAny(System.IO.Path.GetInvalidFileNameChars()) != -1) { } 

Si bien lo que pide el OP es cercano a lo que usa la respuesta actualmente aceptada ( ^[\w\-. ]+$ ), Puede haber otros que vean esta pregunta que tenga restricciones aún más específicas.

En primer lugar, ejecutándose en una máquina que no sea de EE. UU. / GB, \w permitirá una amplia gama de caracteres no deseados de idiomas extranjeros, de acuerdo con las limitaciones del OP.

En segundo lugar, si la extensión del archivo está incluida en el nombre, esto permite todo tipo de nombres extraños, aunque válidos, como el file .txt o el file...txt .

En tercer lugar, si simplemente está cargando los archivos a su sistema de archivos, es posible que desee una lista negra de archivos y / o extensiones como estas:

web.config, hosts, .gitignore, httpd.conf, .htaccess

Sin embargo, eso está considerablemente fuera del scope de esta pregunta; Requeriría todo tipo de información sobre la configuración para una buena guía en temas de seguridad. Pensé que debía plantear el asunto, no obstante.

Así que para una solución donde el usuario pueda ingresar el nombre completo del archivo, me gustaría ir con algo como esto:

 ^[a-zA-Z0-9](?[a-zA-Z0-9 ._-]*[a-zA-Z0-9])?\.[a-zA-Z0-9_-]+$ 

Asegura que solo se use el alfabeto inglés, sin espacios iniciales o finales, y asegura el uso de una extensión de archivo con al menos 1 de longitud y sin espacios en blanco.

He probado esto en Regex101 , pero para futuras referencias, este fue mi “test-suite”:

 ## BELOW SHOULD MATCH web.config httpd.conf test.txt 1.1 my long file name.txt ## BELOW SHOULD NOT MATCH - THOUGH VALID æøå.txt hosts .gitignore .htaccess 

En caso de que alguien más necesite validar los nombres de archivo (incluidas las palabras reservadas de Windows y similares), aquí hay una expresión completa: \A(?!(?:COM[0-9]|CON|LPT[0-9]|NUL|PRN|AUX|com[0-9]|con|lpt[0-9]|nul|prn|aux)|[\s\.])[^\\\/:*"?<>|]{1,254}\z

Edición: Para los interesados, aquí hay un enlace a las convenciones de nombres de archivos de Windows: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx

use esta expresión regular ^[a-zA-Z0-9._ -]+$

Este es un cambio menor a la respuesta de los ingenieros.

 string regex = @"^[\w\- ]+[\w\-. ]*$" 

Esto bloqueará ".txt" que no es válido.

El problema es que bloquea "..txt" que es válido

Acabo de crear esto. Previene dos puntos y un punto al final y al principio. Aunque no permite dos puntos.

 ^([a-zA-Z0-9_]+)\.(?!\.)([a-zA-Z0-9]{1,5})(? 

Puede que esté diciendo algo estúpido aquí, pero me parece que estas respuestas no son correctas. En primer lugar, ¿estamos hablando de Linux o Windoze aquí (u otro sistema operativo)?

En segundo lugar, en Windows es (creo) perfectamente legítimo incluir una “$” en un nombre de archivo, por no mencionar Unicode en general. Ciertamente parece posible.

Traté de obtener una fuente definitiva sobre esto … y terminé en la página de Nombre de archivo de Wikip : en particular, la sección “Caracteres y palabras reservados” parece relevante: y esto es, claramente, una lista de cosas que NO se te permite meter en.

Estoy en el mundo de Java. Y, naturalmente, asumí que Apache Commons tendría algo como validateFilename , tal vez en FilenameUtils … pero parece que no (si lo hubiera hecho, todavía sería potencialmente útil para los progtwigdores de C #, ya que el código suele ser bastante fácil de entender, y por lo tanto podría ser traducido). Sin embargo, hice un experimento utilizando el método normalize : para mi decepción, permitió que los caracteres perfectamente inválidos (?, Etc.) se “pasaran”.

La parte de la página de nombre de archivo de Wikip que se menciona arriba muestra que esta pregunta depende del sistema operativo que esté utilizando … pero debería ser posible confeccionar algunas expresiones regulares simples para Linux y Windoze al menos.

Entonces encontré una forma de Java (al menos):

 Path path = java.nio.file.FileSystems.getDefault().getPath( 'bobb??::mouse.blip' ); 

salida:

java.nio.file.InvalidPathException: Char ilegal en el índice 4: bobb ?? :: mouse.blip

… presumiblemente diferentes objetos del sistema de FileSystem tendrán diferentes reglas de validación

Copiado de @Engineer para futuras referencias ya que el punto no se escapó (como debería) en la respuesta más votada.

Esta es la expresión correcta:

 string regex = @"^[\w\-\. ]+$";