2011-10-21 18 views
5

Escribo una expresión regular simple, pero nunca he sido muy bueno en esto.Java Regex a-z, A-Z, 0-9 y (.) (_) (-)

Lo que intento hacer es verificar una cadena (nombre de archivo) para asegurarme de que solo contiene a-z, A-Z, 0-9 o los caracteres especiales de subrayado (_) punto (.) O guión (-).

Aquí es lo que tengo

if(filename.length() < 1 || !filename.matches("^[a-zA-Z0-9[.][_][-]]+")) 
    return false; 
else 
    return true; 

Esto parece funcionar, pero no se ve muy elegante para mí. ¿Hay alguna forma mejor/más legible de escribir esto?

¡Gracias de antemano! Solo trato de aprender a escribir mejor estos insectores.

-Will

+1

Otros han respondido a la pregunta de expresiones regulares también, pero tengo curiosidad por la que comprueba la longitud de la cadena es mayor que 1. Si la cadena es "", no puede coincidir con ' "^. +" ' – kojiro

+0

Buen punto. Fue sobrante de una implementación anterior. ¡Gracias! –

Respuesta

10

No necesita usar [] dentro de la clase de caracteres.

Por lo tanto, se puede escribir:

^[-a-zA-Z0-9._]+ 

Además, se puede utilizar en lugar de \\wa-zA-Z0-9_.

Por lo tanto, la expresión regular sería:

^[-\\w.]+ 

Además, esta expresión regular coincidirá con una cadena como StackOverflow 22.10$$2011 por el consumo de StackOverflow 22.10. Si necesita que su cadena a consistir por completo de los caracteres, que debe terminar el patrón con $ - al final de la cadena:

^[-\\w.]+$ 
+0

De hecho, en la mayoría de los sabores de expresiones regulares esos corchetes adicionales se tratarían como un error de sintaxis. –

+0

¡Gracias! Esto se ve mucho mejor –

+0

El uso de \\ w permitirá cualquier carácter UTF-8, no solo a-z y A-Z. También ten en cuenta que. coincide con cualquier personaje y necesita ser escapado si te refieres a un literal '.' –

1
try { 
    boolean foundMatch = subjectString.matches("^[\\w.-]+$"); 
} catch (PatternSyntaxException ex) { 
    // Syntax error in the regular expression 
} 

probar esto.

Básicamente \ w es una abreviatura de [a-zA-Z_0-9] y simplemente agrego los otros dos caracteres que desea.

+0

No conozco el motor de recuperación de Java, pero generalmente debe anclarlo al comienzo de la cadena, o bien se aceptará "@ # $% @ # $% foo". –

+0

@OscarKorz Ya había agregado las anclas antes de ver el comentario m8 :) – FailedDev

+0

El método 'matches()' de Java ancla automáticamente la coincidencia en ambos extremos, pero no hace daño usar anclas explícitas, y creo que es una buena política hacerlo asi que. Sin embargo, no veo el sentido de esa anticipación (es decir, '(? = [\\ w .-] + $)').Además, tenga en cuenta que PatternSyntaxException es una RuntimeException; no es necesario que lo atrapes. –

0

Aquí es un método que es más caro (ya que en realidad toca el disco), pero será plataforma cruzada.

Básicamente, crea un archivo con el nombre de pila y lo elimina si no existía anteriormente. Si intentó crear un archivo con un nombre no válido, arroja un error. Así que no importa en qué sistema se encuentre, le dirá si el nombre del archivo era correcto.

Ahora viola una regla general (que usa excepciones para determinar el flujo del programa) y tiene la desventaja de ir al disco. Pero es un enfoque diferente y podría darte ideas que puedas usar.

public boolean isValidFileName(final String fileName) { 
    final File file = new File(fileName); 
    final boolean isValid = true; 
    try { 
     if (file.createNewFile()) { 
      file.delete(); 
     } 
    } catch (IOException e) { 
     isValid = false; 
    } 
    return isValid; 
} 
+0

Esto arrojará potencialmente resultados diferentes en diferentes plataformas. Eso es lo opuesto a lo que generalmente se entiende por multiplataforma, tal como lo entiendo. –

+0

La idea es que proporciona una interfaz para la funcionalidad común, pero implementada diferentemente en diferentes plataformas. Es porque cada uno lo hace diferente que esto funciona tan bien. El único problema real es cuando tienes una plataforma que le dice a otra plataforma lo que está bien o lo que no. Y como dije esto solo un pensamiento para dar una avenida para otras ideas. – corsiKa

Cuestiones relacionadas