2010-03-24 8 views
10

Mi primera pregunta y estoy emocionado ... He estado al acecho desde el lanzamiento y amo el sitio, sin embargo me disculpo por cualquier error de novato, formateo, etc. ...¿Por qué esta data YYYY-MM-DD regex falla en Java?

Estoy intentando validar el formato de un campo de cadena que contiene una fecha en Java. Recibiremos la fecha en una cadena, validaré su formato antes de analizarlo en un objeto Date real. El formato que se transfiere tiene el formato AAAA-MM-DD. Sin embargo, yo estoy atascado en una de mis pruebas, si paso en "1999-12-33" la prueba se producirá un error (como debe ser con un número de día 33) con este patrón incompleta:

((19|20)\\d{2})-([1-9]|0[1-9]|1[0-2])-([12][0-9]|3[01])

Sin embargo, como cuanto añada los caracteres en negrita a continuación pasa la prueba (pero no debe)

((19|20)\\d{2})-([1-9]|0[1-9]|1[0-2])-(0[1-9]|[1-9]|[12][0-9]|3[01])

* nota adicional, sé que puedo cambiar el 0[1-9]|[1-9] en 0?[1-9] pero quería romper todo, hasta su formato más sencillo para tratar de encontrar por qué esto no está funcionando.

Aquí está la prueba de chatarra He reunido a ejecutar a través de todos los diferentes escenarios fecha:

import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

public class scrapTest { 
    public scrapTest() { 
    } 

    public static void main(String[] args) { 

     scrapTest a = new scrapTest(); 
     boolean flag = a.verfiyDateFormat("1999-12-33"); 
    } 

    private boolean verfiyDateFormat(String dateStr){ 
     Pattern datePattern = Pattern.compile("((19|20)\\d{2})-([1-9]|0[1-9]|1[0-2])-(0[1-9]|[1-9]|[12][0-9]|3[01])"); 
     Matcher dateMatcher = datePattern.matcher(dateStr); 
     if(!dateMatcher.find()){ 
      System.out.println("Invalid date format!!! -> " + dateStr); 
      return false; 
     } 
     System.out.println("Valid date format."); 
     return true; 
    } 
} 

he estado programando durante unos 10 años, pero muy nuevo en Java, por lo que no dude en explicar nada tan elemental como te parezca.

Respuesta

8

Creo que es porque usted está utilizando en lugar de dateMatcher.find()dateMatcher.matches(). El primero busca una coincidencia, el último trata de hacer coincidir toda la cadena. Vea el API page. Así que, básicamente, los primeros 3 de 33 coincidirán con el [1-9] que acaba de agregar y el segundo 3 no será igualado por nada, pero el método aún devuelve verdadero.

+0

Gracias, esto fue todo. .matches coincidió correctamente con todo el patrón. – ProfessionalAmateur

+0

No hay problema, mi placer :) – miorel

5

(0 [1-9] | [1-9] | [12] [0-9] | 3 [01])

el segundo caso, [1-9], parece ser el la parte que está teniendo éxito como no tiene una prueba para el final de la cadena.

Se emparejan 03/12/1999, no 1999-12-33

1

Como Broam dijo, su patrón se encuentra parte de la fecha a la altura, para que coincida con la cadena de entrada entera, utilice:

if (!dateMatcher.matches()) { 

en lugar de find().

2
No

realmente una respuesta a la pregunta, sino una sugerencia: escribir una expresión regular más simple, y luego hacer la validación numérica en Java, en lugar de en su expresión regular:

(\\d{4})-(\\d{2})-(\\d{2})

Partido esto contra su entrada, extraer el grupos relevantes y convertir a enteros, luego verifique las partes de año, mes y día para asegurarse de que estén dentro de un rango aceptable.

3

¿Qué le parece usar SimpleDateFormat solo para eso?

 
Date d = new SimpleDateFormat("yyyy-MM-dd").parse(somestring); 
if (d == null) { 
    // somestring is not a Date 
} else { 
    // d is the Date 
} 

Docs para SimpleDateFormat

+0

Lo raro es que esto: formato SimpleDateFormat = new SimpleDateFormat ("yyyyMMdd") coincide con esto: "2015-06-10" –

Cuestiones relacionadas