Foros del Web » Programando para Internet » Javascript »

[SOLUCIONADO] Expresión regular para nombre de archivo

Estas en el tema de Expresión regular para nombre de archivo en el foro de Javascript en Foros del Web. Hola! Juro por mi madre muerta! (no es cierto, no ha muerto aún, ), que busqué en la red la expresión regular para esto, pero ...
  #1 (permalink)  
Antiguo 16/11/2014, 22:10
Avatar de berkeleyPunk  
Fecha de Ingreso: febrero-2013
Ubicación: México :C
Mensajes: 565
Antigüedad: 11 años, 2 meses
Puntos: 22
Pregunta Expresión regular para nombre de archivo

Hola!

Juro por mi madre muerta! (no es cierto, no ha muerto aún, ), que busqué en la red la expresión regular para esto, pero no encontré nada! Así que pido la ayuda de Foros del Web, ya que vaya que las expresiones regulares se complican algo.

Veamos, tenemos un input file:
Código HTML:
Ver original
  1. <input type="file" name="archivo" onchange="validar_nombre_de_archivo(this)">

Pero queremos que el nombre del archivo que se suba tenga cierto formato:
  1. letras de la A a la Z
  2. números del 0 al 9
  3. guiones medios
  4. guiones bajos
  5. sin espacios
  6. y la extensión, claro
Algo así como: mi-numero-es-el-17.pdf
Y no algo como: mi número es el 17.pdf


He comenzado así, pero la cosa no basta, evidentemente:
Código Javascript:
Ver original
  1. function validar_nombre_de_archivo(inputFile) {
  2.  
  3.     patronNombreDeArchivo = /[a-z0-9]+.pdf/;
  4.  
  5.     if(patronNombreDeArchivo.test(inputFile.value) ) {
  6.         alert('El nombre del archivo coincide con el patron!');
  7.     }
  8.     else {
  9.         alert('El nombre del archivo NO coincide!');
  10.     }
  11. }

Alguna ayuda por favor!


Saludos!
  #2 (permalink)  
Antiguo 16/11/2014, 23:59
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: Expresión regular para nombre de archivo

Deberías de tomar solo el nombre del archivo, pues, de esa forma, tomas el nombre y ruta.

Código Javascript:
Ver original
  1. function validar_nombre_de_archivo(inputFile){
  2.     var valor = inputFile.value,
  3.         archivo = valor.substr(valor.lastIndexOf("\\") + 1);
  4.     if (/[a-z\d\-_\.]+\.pdf/gi.test(archivo))
  5.         console.log("Bien");
  6.     else
  7.         console.log("Mal");
  8. }

Con el método lastIndexOf, obtenemos la porción de la cadena a partir del último contra-slash —al cual escapo para que este no escape a las comillas que le siguen— y avanzo una posición hacia la derecha, tomando así solo al nombre del archivo y su extensión. Luego, si el nombre contiene letras, números, guiones, guiones bajos y/o puntos, además de tener extensión '.pdf', será válido, caso contrario, no lo será.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #3 (permalink)  
Antiguo 17/11/2014, 12:06
Avatar de berkeleyPunk  
Fecha de Ingreso: febrero-2013
Ubicación: México :C
Mensajes: 565
Antigüedad: 11 años, 2 meses
Puntos: 22
Pregunta Respuesta: Expresión regular para nombre de archivo

Cita:
Iniciado por Alexis88 Ver Mensaje
...obtenemos la porción de la cadena a partir del último contra-slash... tomando así solo al nombre del archivo y su extensión
Hola Alexis88, como siempre, gracias.

Híjole mano, si tienes tiempo a ver si me ayudas con estas dudas:

1) Entonces, corroborando, si no empleamos el lastIndexOf el value del input agarra todo, que es la ruta completa del archivo en el disco duro del cliente.
2) ¿La expresión regular [a-z] incluye letras acentuadas? (parece que sí).
3) Si la respuesta a la pregunta anterior es SÍ, entonces por qué tu código valida MAL esto: áéíóú.pdf, pero valida BIEN esto: áéíóú-ñoño.pdf

Modifiqué un poquillo tu código para hacer que la validación incluya lo que se considera caracteres especiales: acentos, signos varios, etc. Pero como no me salió poner toda la validación en una sola expresión regular, pues hice la validación en varios niveles :

Código Javascript:
Ver original
  1. function validar_nombre_de_archivo(inputFile) {
  2.     var valor   = inputFile.value;
  3.     var archivo = valor.substr(valor.lastIndexOf("\\") + 1);
  4.  
  5.     if (!/[\s]+/gi.test(archivo)) {
  6.         console.log("No tiene espacios. ADELANTE");
  7.         if (!/[áãàáäâªèéëêìíïïòóöôùúüûñ稺~#@!%&¡¿}¨´><`;,:()\|\·\$\^\[\]\?\+\\]+/gi.test(archivo)) {
  8.             console.log("No tiene caracteres especiales. ADELANTE.");
  9.         }
  10.         else {
  11.             console.log("Tiene caracteres especiales. ALTO.");
  12.         }
  13.     }
  14.     else {
  15.         console.log("Tiene espacios. ALTO");
  16.     }
  17. }


Hasta donde sé, esto:
Código Javascript:
Ver original
  1. if (/[^\s]+/gi.test(archivo)) {...}
debería leerse como: si no hay espacios... Pero no me funciona, por eso utilicé el operador !

Maestro, ¿apruebas esta validación? (sin contar lo feo que se ve al emplear tantas líneas )

Saludos!
  #4 (permalink)  
Antiguo 17/11/2014, 12:50
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: Expresión regular para nombre de archivo

Paso a responderte punto por punto:
  1. Claro, es lo que te dije.
  2. No. Para eso, debes de agregarlas a la expresión regular. Recuerda que, en el idioma inglés, no se tildan las vocales.
  3. Beto a saber. Supongo que será porque la segunda cadena contiene algunos de los elementos que la expresión considera válidos, pero no estoy seguro. Quizá en el sub-foro de expresiones regulares, puedan darte una explicación.

Por otra parte, con que no incluyas el caracter de espacio en la expresión regular, debería de bastar, es decir, si el texto contiene espacios y la expresión regular, no, entonces, al momento de hacer la comparación, al encontrar un caracter no válido, debería de mostrarse el mensaje de error. Creo también que deberías de ser un poco menos permisivo con respecto al formato del nombre del archivo, es decir, creo que hasta las tildes, eñes, guiones y guiones bajos, está bien, pero ya las diéresis y las tildes invertidas, entre otros caracteres especiales que veo en tu expresión regular, me parecen una exageración. Es solo una opinión.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #5 (permalink)  
Antiguo 17/11/2014, 13:11
Avatar de berkeleyPunk  
Fecha de Ingreso: febrero-2013
Ubicación: México :C
Mensajes: 565
Antigüedad: 11 años, 2 meses
Puntos: 22
Respuesta: Expresión regular para nombre de archivo

Cita:
Iniciado por Alexis88 Ver Mensaje
...Creo también que deberías de ser un poco menos permisivo con respecto al formato del nombre del archivo...
Creo que quisiste decir más permisivo

Bueno, por otro lado, te comento por qué no soy tan permisivo, o sea, muy estricto con dicha validación. Te comento para que me des tu opinión.

Hice un pequeño administrador que permite al usuario subir un PDF a un sitio web. La cosa es que cuando le comenté a un compañero que ya estaba listo, me preguntó: ¿y qué pasa si el nombre de archivo tiene caracteres raros? Dentro de mí, dije: ¡Diablos! Así que pensé que lo que aquella persona quiso decir es que un nombre de archivo no debe tener caracteres raros porque puede causar algún error. Por eso me propuse validar el nombre del archivo antes de permitir subirlo.

Mira, maestro, el nombre del archivo que se sube se guarda en una base de datos. Y ahora que veo (y es literal, ahora exactamente) veo que los signos $ y %, por ejemplo, se guardan en la base de datos como tales, así como los espacios. Es decir, que no son considerados caracteres especiales. Eso sí, las vocales acentuadas las cambia por sus entidades HTML. (Mi BD tiene codificación UTF-8 General CI)

1) Ya que estamos aquí, entonces te pregunto, ¿sabes qué se considera un caractér especial?
2) Más aún, visto que la BD guarda casi litealmente el nombre del archivo que se sube (excepto por las letras acentuadas), ¿es necesaria la validación del lado del cliente?

Saludos!

Última edición por berkeleyPunk; 17/11/2014 a las 13:17
  #6 (permalink)  
Antiguo 17/11/2014, 13:24
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 2 meses
Puntos: 260
Sonrisa Respuesta: Expresión regular para nombre de archivo

Hola,

Posiblemente te sea de alguna ayuda, normalmente, cuando haces este tipo de aplicaciones no guardas el archivo con el nombre original, por varios motivos.

Cuando subes el archivo, usas cualquier valor único, como un GUID, un auto-numérico en la base de datos, el timestamp mas el nombre del usuario o cualquier otra información que te permita individualizar el nombre del archivo, y con ese nombre lo guardas en disco.

Puedes guardar el nombre del archivo original en la base de datos como referencia para servir el archivo de vuelta, es decir, cuando alguien quiera el archivo con su nombre original, lees el archivo con nombre {01264-125... etc} y en el header del response le pones el nombre original.

De esa forma te evitas muchos dolores de cabeza, pero para gustos los colores,

Saludos,

Cita:
Iniciado por berkeleyPunk Ver Mensaje
... ¿y qué pasa si el nombre de archivo tiene caracteres raros? ...
Ahora piensa que pasa si suben dos archivos con el mismo nombre.

Saludos,
  #7 (permalink)  
Antiguo 17/11/2014, 13:37
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: Expresión regular para nombre de archivo

Lo que menciona HackmanC es correcto, de hecho, yo también lo hago de esa forma, aunque todo el proceso lo hago del lado del servidor pues es más seguro.

Lo de los caracteres 'raros', no debería de ser una preocupación, en especial si sigues decides cambiar el nombre al momento de guardarlo.

Con lo que sí debes de tener cuidado es con que no enmascaren un archivo no permitido (por ejemplo, un script malicioso) como un archivo PDF o de otro tipo. Para esto, te recomiendo leer acerca de las funciones de Fileinfo.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #8 (permalink)  
Antiguo 17/11/2014, 15:22
Avatar de berkeleyPunk  
Fecha de Ingreso: febrero-2013
Ubicación: México :C
Mensajes: 565
Antigüedad: 11 años, 2 meses
Puntos: 22
De acuerdo Respuesta: Expresión regular para nombre de archivo

Cita:
Iniciado por HackmanC Ver Mensaje
...Cuando subes el archivo, usas cualquier valor único, como un GUID, un auto-numérico en la base de datos, el timestamp mas el nombre del usuario o cualquier otra información que te permita individualizar el nombre del archivo, y con ese nombre lo guardas en disco...
Hola HackmanC. Qué bueno que lo mencionas. Sí, yo ya me había propuesto hacer esa modificación pero lo había olvidado por completo. Lo que tenía pensado es guardar el nombre del archivo tal como venía más un prefijo, que fuera un número aleatorio. Pero veo que tu recomendación es infinitamente mejor. Voy a usar el timestamp.

Cita:
Iniciado por Alexis88 Ver Mensaje
..Con lo que sí debes de tener cuidado es con que no enmascaren un archivo no permitido (por ejemplo, un script malicioso) como un archivo PDF o de otro tipo...
En este punto sí he hecho algo al respecto, no sé si suficiente, pero sí algo, al menos: he verificado que el tipo MIME corresponda con un PDF:

Código PHP:
if ( is_uploaded_file$_FILES['archivo']['tmp_name']) ) {
    if( 
$_FILES['archivo']['size'] < (10485760) ) {     // 10,485,760 Kylobytes = 10 megas
        
if ( $_FILES['archivo']['type'] == "application/pdf" ) {...} 
Saludos!
  #9 (permalink)  
Antiguo 17/11/2014, 16:01
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: Expresión regular para nombre de archivo

Eso no basta. De esa forma, solo obtienes el tipo de archivo que bien podría estar enmascarado. Con las funciones Fileinfo, puedes obtener el tipo real.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #10 (permalink)  
Antiguo 17/11/2014, 20:08
Avatar de berkeleyPunk  
Fecha de Ingreso: febrero-2013
Ubicación: México :C
Mensajes: 565
Antigüedad: 11 años, 2 meses
Puntos: 22
De acuerdo Respuesta: Expresión regular para nombre de archivo

Ok, señores. He hecho algunos cambios según sus comentarios.

Ahora la pequeña aplicación en PHP de la que hablaba (¿está bien dicho, aplicación web? Suena muy pretencioso, ¿no? ) cuenta con lo siguiente:

  1. Decidí ya no validar el nombre del archivo por el lado del cliente: que el usuario suba el archivo con el nombre que se le antoje.
  2. Cuando PHP se ponga en acción, que se verifique el tipo MIME del archivo subido, pero no con $_FILES['archivo']['type'] sino con finfo_open(FILEINFO_MIME_TYPE)
  3. Y el nombre del archivo se guarda en la base de datos compuesto inicialmente por la fecha, luego la hora (hora, minútos y segundos) y termine con el nombre de la sección donde se subió.

Bueno, pues eso es todo.
Saludos y gracias, nuevamente!

Etiquetas: Ninguno
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:37.