Coincidencia de expresión regular para probar un año válido

89

Dado un valor, quiero validarlo para verificar si es un año válido. Mi criterio es simple donde el valor debe ser un número entero con 4caracteres. Sé que esta no es la mejor solución ya que no permitirá años antes 1000y permitirá años como 5000. Este criterio es adecuado para mi escenario actual.

Lo que se me ocurrió es

\d{4}$

Si bien esto funciona, también permite valores negativos.

¿Cómo me aseguro de que solo se permitan números enteros positivos?

Ranhiru Jude Cooray
fuente
fwiw creé un proyecto node.js, to-regex-range para crear automáticamente estos rangos. Es más difícil de lo que parece si necesita generar la expresión regular para probar durante un rango de años.
jonschlinkert
¿Por qué limitar su validación a años de 4 dígitos? longnow.org
Dan Temple

Respuestas:

76

Necesita agregar un ancla de inicio ^como:

^\d{4}$

Su expresión regular \d{4}$coincidirá con cadenas que terminen con 4 dígitos . Por lo tanto -1234, se aceptarán entradas similares .

Al agregar el ancla de inicio, solo coincide con las cadenas que comienzan y terminan con 4 dígitos, lo que significa que deben contener solo 4 dígitos.

codaddict
fuente
2
¡Maldición! El mío era tan defectuoso que incluso habría aceptado whateverblahblah2323. Ahora entiendo por qué un poco de aprendizaje es peligroso: O
Ranhiru Jude Cooray
62
Esto se romperá en el año 10,000.
sferik
16
@sferik: No importa. El cartel original indicaba específicamente que quería comprobar si había cuatro personajes. No dijo que quería que el año 10,000 fuera una entrada válida, por lo que aceptar 10000sería un error.
markusk
4
@sferik: El programa habrá desaparecido durante siglos para entonces. Si no es así, es mejor preocuparse por 9.000 años en el futuro. Siguiendo el principio de YAGNI, el enfoque es válido.
Phil
182

Años de 1000 a 2999

^[12][0-9]{3}$

Para 1900-2099

^(19|20)\d{2}$
r92
fuente
14
Esta es una solución mucho mejor
mk_89
10
Es mejor usar el grupo que no captura:^(?:19|20)\d{2}$
Eldar Agalarov
¿Cómo validaría un año de 4 dígitos entre 2011 y 2099?
mcquaim
¿Cómo puedo agregar (19|20)\d{2}a mi expresión regular para validar un formato de fecha de nacimiento? Esta es mi expresión regular /^[0-9]{1,2}\/(0[1-9])|(1[0-2])\/[0-9]{4}$/. Quiero asegurarme de que el año siempre tenga 4 dígitos y comience a marchitarse 19 ** o 20 **
ltdev
Use ^ (19 | 2 [0-9]) \ d {2} $ para los años 1900 - 2999
MarcoZen
22

La respuesta "aceptada" a esta pregunta es incorrecta y miope.

Es incorrecto porque coincidirá con cadenas como 0001, que no es un año válido.

Es miope en el sentido de que no coincidirá con ningún valor por encima de 9999. ¿Ya hemos olvidado las lecciones del año 2000 ? En su lugar, use la expresión regular:

^[1-9]\d{3,}$

Si necesita hacer coincidir años en el pasado, además de años en el futuro, puede usar esta expresión regular para hacer coincidir cualquier número entero positivo:

^[1-9]\d*$

Incluso si no espera fechas del pasado, es posible que desee utilizar esta expresión regular de todos modos, en caso de que alguien invente una máquina del tiempo y quiera llevarse su software con ellos.

Nota: Esta expresión regular coincidirá con todos los años, incluidos los anteriores al año 1, ya que normalmente se representan con una designación BC en lugar de un número entero negativo. Por supuesto, esta convención podría cambiar en los próximos milenios, por lo que su mejor opción es hacer coincidir cualquier número entero, positivo o negativo, con la siguiente expresión regular:

^-?[1-9]\d*$
sferik
fuente
3
No, probablemente no lo hará. Pero alguien (¿arqueólogo? ¿Historiador?) Podría necesitar igualar los años de hace 8000 años. : D Y Doc Brown podría necesitarlo ...
Jaime
1
Usé esto para limitar el rango de 1000-9999 ^ [1-9] \\ d {3} $ eso es porque la aplicación a la que tenemos que proporcionar datos, acepta solo números de 4 dígitos :(
MatPag
Respuesta impresionante. Haría lo siguiente para aceptar el año 0 también: ^ (-? [1-9] \ d * | 0) $
Kosta Kontos
10

Esto funciona de 1900 a 2099:

/(?:(?:19|20)[0-9]{2})/
jonschlinkert
fuente
me parece que solo iría a 2099. Por cierto, el OP está preguntando cómo permitir solo números positivos de 4 dígitos.
DeanOC
bah, 2099 es lo que quise decir. Gracias. y ahora veo la parte de enteros positivos.
jonschlinkert
Creé
5

Sobre la base de la respuesta de @ r92, para los años 1970-2019:

(19[789]\d|20[01]\d)
Renaud
fuente
Tu respuesta lo permite197999
avalancha1
No creo que lo haga ... La primera parte de la expresión regular coincide con el número que comienza con 19, luego cualquiera de 7,8 o 9, seguido de un número ÚNICO. La expresión regular 19[789]\d\d\dpermitiría197999
Renaud
1
/(19[789]\d|20[01]\d)/.test(1970324) >> true
avalancha1
sí, coincidirá con los primeros 4 números ( 1970), no con los últimos 3. ¿Sobre qué (19[789]\d|20[01]\d)[^0-9]? Eso coincidiría 1970 324pero no1970324
Renaud
1
Encontré este útil para encontrar el año de la película a partir de un nombre de archivo ... en este caso, queremos cosas de la década de 1930 en adelante ... pero luego excluimos el 1024 que se agrega al final para la calidad del video
Adrian Hum
2

En teoría, la opción de 4 dígitos es correcta. Pero en la práctica, sería mejor tener un rango de 1900-2099.

Además, debe ser un grupo no capturador. Muchos comentarios y respuestas proponen capturar agrupaciones que no son adecuadas en mi humilde opinión. Porque para hacer coincidir podría funcionar, pero para extraer coincidencias usando expresiones regulares, extraerá números de 4 dígitos y números de dos dígitos (19 y 20) también debido a la parántesis.

Esto funcionará para una coincidencia exacta utilizando grupos que no capturan:

(?:19|20)\d{2}

Adil Aliyev
fuente
1

puede ir con algo como [ ^-]\d{4}$: evita que el signo menos -esté antes de sus 4 dígitos.
también puede usar ^\d{4}$con ^para capturar el comienzo de la cadena. Depende de tu escenario en realidad ...

Pierroz
fuente
1

Para probar un año en una cadena que contiene otras palabras junto con el año, puede usar la siguiente expresión regular: \ b \ d {4} \ b

Dhyey
fuente
Esto era exactamente lo que necesitaba, la respuesta aceptada no parece ser una PCRE válida.
Prometheus
0

Podría convertir su número entero en una cadena. Como el signo menos no coincidirá con los dígitos, no tendrá años negativos.

Comradin
fuente
0

Yo uso esta expresión regular en Java ^(0[1-9]|1[012])[/](0[1-9]|[12][0-9]|3[01])[/](19|[2-9][0-9])[0-9]{2}$

Obras desde 1900 hasta 9999

R2Rivs
fuente
0

/ ^ \ d {4} $ / Esto comprobará si una cadena consta de solo 4 números. En este escenario, para ingresar un año 989, puede dar 0989 en su lugar.

Dayz
fuente
0

Si necesita hacer coincidir AAAA o AAAAMMDD, puede usar:

^((?:(?:(?:(?:(?:[1-9]\d)(?:0[48]|[2468][048]|[13579][26])|(?:(?:[2468][048]|[13579][26])00))(?:0?2(?:29)))|(?:(?:[1-9]\d{3})(?:(?:(?:0?[13578]|1[02])(?:31))|(?:(?:0?[13-9]|1[0-2])(?:29|30))|(?:(?:0?[1-9])|(?:1[0-2]))(?:0?[1-9]|1\d|2[0-8])))))|(?:19|20)\d{2})$
Benjamín Goodacre
fuente
0

También puedes usar este.

([0-2][0-9]|3[0-1])\/([0-1][0-2])\/(19[789]\d|20[01]\d)
Ranjeet Chouhan
fuente
Quieren coincidir solo con el año. Por otra parte sus partidos de expresiones regulares 00/00/2000o 31/02/1999y muchas fechas más falsos.
Toto
Podría ayudarte ([0-2] [0-9] | 3 [0-1]) \ / ([0-1] [0-2]) \ / (19 [789] \ d | 20 [01 ] \ d)
Ranjeet Chouhan
(0[1-9]|1[0-2])es una expresión mucho mejor para el mes
EZ-C