yyyy validar solo regulares regular palabra mayor letras fecha expresiones expresion exacta espacios actual regex date

regex - solo - validar fecha javascript expresion regular



Expresión regular para unir fechas válidas (15)

Intento escribir una expresión regular que valida una fecha. La expresión regular debe coincidir con la siguiente

  • M / D / YYYY
  • MM / DD / YYYY
  • Los meses de un solo dígito pueden comenzar con un cero inicial (p. Ej .: 03/12/2008)
  • Los días de un solo dígito pueden comenzar con un cero inicial (p. Ej .: 3/02/2008)
  • NO PUEDE incluir el 30 de febrero o el 31 de febrero (p. Ej .: el 31/1/2008)

Hasta ahora tengo

^(([1-9]|1[012])[-/.]([1-9]|[12][0-9]|3[01])[-/.](19|20)/d/d)|((1[012]|0[1-9])(3[01]|2/d|1/d|0[1-9])(19|20)/d/d)|((1[012]|0[1-9])[-/.](3[01]|2/d|1/d|0[1-9])[-/.](19|20)/d/d)$

Esto coincide adecuadamente, EXCEPTO, sigue incluyendo 2/30/2008 y 2/31/2008.

¿Alguien tiene una mejor sugerencia?

Editar: Encontré la respuesta en RegExLib

^((((0[13578])|([13578])|(1[02]))[//](([1-9])|([0-2][0-9])|(3[01])))|(((0[469])|([469])|(11))[//](([1-9])|([0-2][0-9])|(30)))|((2|02)[//](([1-9])|([0-2][0-9]))))[//]/d{4}$|^/d{4}$

Coincide con todos los meses válidos que siguen el formato MM / DD / YYYY.

Gracias a todos por la ayuda.


Versión Perl 6

rx{ ^ $<month> = (/d ** 1..2) { $<month> <= 12 or fail } ''/'' $<day> = (/d ** 1..2) { given( +$<month> ){ when 1|3|5|7|8|10|12 { $<day> <= 31 or fail } when 4|6|9|11 { $<day> <= 30 or fail } when 2 { $<day> <= 29 or fail } default { fail } } } ''/'' $<year> = (/d ** 4) $ }

Después de usar esto para verificar la entrada, los valores están disponibles en $/ o individualmente como $<month> , $<day> , $<year> . (esos son solo la sintaxis para acceder a los valores en $/ )

No se ha intentado verificar el año, o no coincide con el 29 de febrero en años no bisiestos.


Versión ampliada Perl

Tenga en cuenta el uso del modificador /x .

/^( ( ( # 31 day months (0[13578]) | ([13578]) | (1[02]) ) [//] ( ([1-9]) | ([0-2][0-9]) | (3[01]) ) ) | ( ( # 30 day months (0[469]) | ([469]) | (11) ) [//] ( ([1-9]) | ([0-2][0-9]) | (30) ) ) | ( # 29 day month (Feb) (2|02) [//] ( ([1-9]) | ([0-2][0-9]) ) ) ) [//] # year /d{4}$ | ^/d{4}$ # year only /x

Original

^((((0[13578])|([13578])|(1[02]))[//](([1-9])|([0-2][0-9])|(3[01])))|(((0[469])|([469])|(11))[//](([1-9])|([0-2][0-9])|(30)))|((2|02)[//](([1-9])|([0-2][0-9]))))[//]/d{4}$|^/d{4}$


Versión perceptible de Perl 5.10

/ (?: (?<month> (?&mon_29)) [//] (?<day>(?&day_29)) | (?<month> (?&mon_30)) [//] (?<day>(?&day_30)) | (?<month> (?&mon_31)) [//] (?<day>(?&day_31)) ) [//] (?<year> [0-9]{4}) (?(DEFINE) (?<mon_29> 0?2 ) (?<mon_30> 0?[469] | (11) ) (?<mon_31> 0?[13578] | 1[02] ) (?<day_29> 0?[1-9] | [1-2]?[0-9] ) (?<day_30> 0?[1-9] | [1-2]?[0-9] | 30 ) (?<day_31> 0?[1-9] | [1-2]?[0-9] | 3[01] ) ) /x

Puede recuperar los elementos por nombre en esta versión.

say "Month=$+{month} Day=$+{day} Year=$+{year}";

(No se ha intentado restringir los valores del año).


Aquí está el Reg ex que coincide con todas las fechas válidas, incluidos los años bisiestos. Formatos aceptados mm / dd / aaaa o mm-dd-aaaa o formato mm.dd.aaaa

^(?:(?:(?:0?[13578]|1[02])(//|-|/.)31)/1|(?:(?:0?[1,3-9]|1[0-2])(//|-|/.)(?:29|30)/2))(?:(?:1[6-9]|[2-9]/d)?/d{2})$|^(?:0?2(//|-|/.)29/3(?:(?:(?:1[6-9]|[2-9]/d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(//|-|/.)(?:0?[1-9]|1/d|2[0-8])/4(?:(?:1[6-9]|[2-9]/d)?/d{2})$

cortesía Asiq Ahamed


Aterricé aquí porque el título de esta pregunta es amplio y estaba buscando una expresión regular que pudiera usar para unirme a un formato de fecha específico (como el OP). Pero luego descubrí que, como muchas de las respuestas y comentarios han destacado exhaustivamente, existen muchas trampas que hacen que construir un patrón efectivo sea muy complicado cuando se extraen fechas que están mezcladas con datos de fuente no estructurada o de baja calidad.

En mi exploración de los problemas, he creado un sistema que le permite construir una expresión regular organizando juntas cuatro sub-expresiones más simples que coinciden en el delimitador, y rangos válidos para los campos de año, mes y día en el orden Necesitas.

Estos son :-

Delímetros

[^/w/d/r/n:]

Esto coincidirá con cualquier cosa que no sea un carácter de palabra, un dígito, un retorno de carro, una nueva línea o dos puntos. El colon debe estar allí para evitar coincidencias en horarios que parecen fechas (ver mis datos de prueba)

Puede optimizar esta parte del patrón para acelerar la coincidencia, pero esta es una buena base que detecta la mayoría de los delimitadores válidos.

Tenga en cuenta sin embargo; Coincidirá con una cadena con delimitadores mixtos como este 2 / 12-73 que puede no ser una fecha válida.

Valores del año

(/d{4}|/d{2})

Esto coincide con un grupo de dos o 4 dígitos, en la mayoría de los casos esto es aceptable, pero si se trata de datos de los años 0-999 o más allá de 9999, debe decidir cómo manejar eso porque en la mayoría de los casos, 1, 3 o> año de 4 dígitos es basura.

Valores del mes

(0?[1-9]|1[0-2])

Coincide con cualquier número entre 1 y 12 con o sin una nota cero inicial: 0 y 00 no coinciden.

Valores de fecha

(0?[1-9]|[12]/d|30|31)

Coincide con cualquier número entre 1 y 31 con o sin una nota cero inicial: 0 y 00 no coinciden.

Esta expresión coincide con fechas formateadas de fecha, mes y año

(0?[1-9]|[12]/d|30|31)[^/w/d/r/n:](0?[1-9]|1[0-2])[^/w/d/r/n:](/d{4}|/d{2})

Pero también coincidirá con algunas de las fechas de Año, Mes. También se debe reservar con los operadores de límites para garantizar que se selecciona la cadena de fecha completa y evitar que se extraigan subdatos válidos a partir de datos que no están bien formados, es decir, sin etiquetas de límite 20/12/194 coincide con 20/12/19 y 101/12/1974 coincide con el 01/12/1974

Compare los resultados de la siguiente expresión con los de arriba con los datos de prueba en la sección sin sentido (abajo)

/b(0?[1-9]|[12]/d|30|31)[^/w/d/r/n:](0?[1-9]|1[0-2])[^/w/d/r/n:](/d{4}|/d{2})/b

No hay validación en esta expresión regular por lo que una fecha bien formada pero no válida como 31/02/2001 se correspondería. Ese es un problema de calidad de datos, y como otros han dicho, su expresión regular no debería necesitar validar los datos.

Debido a que usted (como desarrollador) no puede garantizar la calidad de los datos de origen que necesita realizar y manejar la validación adicional en su código, si intenta hacer coincidir y validar los datos en el RegEx se vuelve muy complicado y se vuelve difícil soporte sin una documentación muy concisa.

Basura dentro basura fuera.

Habiendo dicho eso, si tiene formatos mixtos donde los valores de fecha varían, y tiene que extraer todo lo que pueda; Puede combinar un par de expresiones juntas de esa manera;

Esta expresión (desastrosa) coincide con las fechas DMY y YMD

(/b(0?[1-9]|[12]/d|30|31)[^/w/d/r/n:](0?[1-9]|1[0-2])[^/w/d/r/n:](/d{4}|/d{2})/b)|(/b(0?[1-9]|1[0-2])[^/w/d/r/n:](0?[1-9]|[12]/d|30|31)[^/w/d/r/n:](/d{4}|/d{2})/b)

PERO no podrá decir si las fechas como el 6/9/1973 son el 6 de septiembre o el 9 de junio. Estoy luchando por pensar en un escenario donde eso no vaya a causar problemas en algún momento, es una mala práctica y no deberías lidiar con eso de esa manera: encuentra al propietario de los datos y golpéalos con el martillo de gobernanza .

Finalmente, si quiere hacer coincidir una cadena YYYYMMDD sin delimitadores, puede sacar algo de incertidumbre y la expresión se ve así:

/b(/d{4})(0[1-9]|1[0-2])(0[1-9]|[12]/d|30|31)/b

Pero tenga en cuenta que coincidirá en valores bien formados pero no válidos como 20010231 (31 de febrero) :)

Datos de prueba

Al experimentar con las soluciones en este hilo, terminé con un conjunto de datos de prueba que incluye una variedad de fechas válidas y no válidas y algunas situaciones complicadas en las que puede o no desear coincidir, es decir, tiempos que pueden coincidir con fechas y fechas múltiples líneas

Espero que esto sea útil para alguien.

Valid Dates in various formats Day, month, year 2/11/73 02/11/1973 2/1/73 02/01/73 31/1/1973 02/1/1973 31.1.2011 31-1-2001 29/2/1973 29/02/1976 03/06/2010 12/6/90 month, day, year 02/24/1975 06/19/66 03.31.1991 2.29.2003 02-29-55 03-13-55 03-13-1955 12/24/1974 12/30/1974 1/31/1974 03/31/2001 01/21/2001 12/13/2001 Match both DMY and MDY 12/12/1978 6/6/78 06/6/1978 6/06/1978 using whitespace as a delimiter 13 11 2001 11 13 2001 11 13 01 13 11 01 1 1 01 1 1 2001 Year Month Day order 76/02/02 1976/02/29 1976/2/13 76/09/31 YYYYMMDD sortable format 19741213 19750101 Valid dates before Epoch 12/1/10 12/01/660 12/01/00 12/01/0000 Valid date after 2038 01/01/2039 01/01/39 Valid date beyond the year 9999 01/01/10000 Dates with leading or trailing characters 12/31/21/ 31/12/1921AD 31/12/1921.10:55 12/10/2016 8:26:00.39 wfuwdf12/11/74iuhwf fwefew13/11/1974 01/12/1974vdwdfwe 01/01/99werwer 12321301/01/99 Times that look like dates 12:13:56 13:12:01 1:12:01PM 1:12:01 AM Dates that runs across two lines 1/12/19 74 01/12/19 74/13/1946 31/12/20 08:13 Invalid, corrupted or nonsense dates 0/1/2001 1/0/2001 00/01/2100 01/0/2001 0101/2001 01/131/2001 31/31/2001 101/12/1974 56/56/56 00/00/0000 0/0/1999 12/01/0 12/10/-100 74/2/29 12/32/45 20/12/194 2/12-73


Esta expresión regular valida las fechas entre el 01-01-2000 y el 12-31-2099 con separadores coincidentes.

^(0[1-9]|1[012])([- /.])(0[1-9]|[12][0-9]|3[01])/2(19|20)/d/d$


Este no es un uso apropiado de expresiones regulares. Estarías mejor usando

[0-9]{2}/[0-9]{2}/[0-9]{4}

y luego verificar rangos en un lenguaje de nivel superior.


Para controlar una validez de fecha en el siguiente formato:

AAAA / MM / DD o AAAA-MM-DD

Te recomiendo que uses la siguiente expresión regular:

(((19|20)([2468][048]|[13579][26]|0[48])|2000)[/-]02[/-]29|((19|20)[0-9]{2}[/-](0[4678]|1[02])[/-](0[1-9]|[12][0-9]|30)|(19|20)[0-9]{2}[/-](0[1359]|11)[/-](0[1-9]|[12][0-9]|3[01])|(19|20)[0-9]{2}[/-]02[/-](0[1-9]|1[0-9]|2[0-8])))

Partidos

2016-02-29 | 2012-04-30 | 2019/09/31

No coincidencias

2016-02-30 | 2012-04-31 | 2019/09/35

Puede personalizarlo si quiere permitir solo separadores ''/'' o ''-''. Este RegEx controla estrictamente la validez de la fecha y verifica 28,30 y 31 días meses, incluso años bisiestos con 29/02 mes.

Pruébalo, funciona muy bien y evita tu código de muchos errores.

FYI: hice una variante para el horario de SQL. Lo encontrarás allí (busca mi nombre): Expresión regular para validar una marca de tiempo

Los comentarios son bienvenidos :)


Parece que estás exagerando la expresión regular para este propósito. Lo que haría sería usar una expresión regular para que coincida con algunos formatos de fecha y luego usar una función separada para validar los valores de los campos de fecha así extraídos.


Regex no estaba destinado a validar los rangos numéricos (este número debe ser de 1 a 5 cuando el número que le precede es 2 y el número anterior que está por debajo de 6). Solo busca el patrón de ubicación de los números en expresiones regulares. Si necesita validar las cualidades de una fecha, póngala en un objeto de fecha js / c # / vb, e intercalcule los números allí.


Sé que esto no responde a su pregunta, pero ¿por qué no utiliza una rutina de manejo de fechas para verificar si es una fecha válida? Incluso si modifica la expresión regular con una aserción negativa de búsqueda anticipada como (?! 31/0? 2) (es decir, no coincide con 31/2 o 31/02), seguirá teniendo el problema de aceptar 29 02 en años no bisiestos. y sobre un solo formato de fecha de separador.

El problema no es fácil si realmente quieres validar una fecha, mira este hilo del foro .

Para un ejemplo o una forma mejor, en C #, consulte este enlace

Si está utilizando otra plataforma / idioma, infórmenos


Si no conseguiste que funcionaran las sugerencias anteriores, utilizo esto, ya que en cualquier fecha ejecuto esta expresión a través de 50 enlaces, y obtuve todas las fechas en cada página.

^20/d/d-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(0[1-9]|[1-2][0-9]|3[01])$


Si vas a insistir en hacer esto con una expresión regular, te recomendaría algo como:

( (0?1|0?3| <...> |10|11|12) / (0?1| <...> |30|31) | 0?2 / (0?1| <...> |28|29) ) / (19|20)[0-9]{2}

Esto podría permitir leer y comprender.


Un enfoque ligeramente diferente que puede o no serle útil.

Estoy en php.

El proyecto al que se refiere esto nunca tendrá una fecha anterior al 1 de enero de 2008. Por lo tanto, tomo la ''fecha'' inputed y uso strtotime (). Si la respuesta es> = 1199167200, entonces tengo una fecha que me es útil. Si se ingresa algo que no se parece a una fecha, se devuelve -1. Si se ingresa nulo, devuelve el número de fecha de hoy, por lo que primero necesita una verificación para una entrada que no sea nula.

¿Funciona para mi situación, tal vez la tuya también?


var dtRegex = new RegExp(/[1-9/-]{4}[0-9/-]{2}[0-9/-]{2}/); if(dtRegex.test(date) == true){ var evalDate = date.split(''-''); if(evalDate[0] != ''0000'' && evalDate[1] != ''00'' && evalDate[2] != ''00''){ return true; } }