Correspondance d'expression régulière à tester pour une année valide

89

Étant donné une valeur, je veux la valider pour vérifier si c'est une année valide. Mes critères sont simples où la valeur doit être un entier avec des 4caractères. Je sais que ce n'est pas la meilleure solution car elle ne permettra pas des années auparavant 1000et permettra des années comme 5000. Ce critère est adéquat pour mon scénario actuel.

Ce que j'ai trouvé est

\d{4}$

Bien que cela fonctionne, cela permet également des valeurs négatives.

Comment puis-je m'assurer que seuls les entiers positifs sont autorisés?

Ranhiru Jude Cooray
la source
fwiw J'ai créé un projet node.js, to-regex-range pour créer automatiquement ces plages. C'est plus difficile qu'il n'y paraît si vous devez générer l'expression régulière à tester pendant plusieurs années.
jonschlinkert
Pourquoi limiter votre validation à 4 chiffres années? longnow.org
Dan Temple

Réponses:

76

Vous devez ajouter une ancre de départ ^comme:

^\d{4}$

Votre expression régulière \d{4}$correspondra aux chaînes qui se terminent par 4 chiffres . Donc, les entrées comme -1234seront acceptées.

En ajoutant l'ancre de début, vous ne faites correspondre que les chaînes qui commencent et se terminent par 4 chiffres, ce qui signifie qu'elles ne doivent contenir que 4 chiffres.

codaddict
la source
2
Zut! Le mien était si imparfait qu'il aurait même accepté whateverblahblah2323. Maintenant je comprends pourquoi un peu d'apprentissage est dangereux: O
Ranhiru Jude Cooray
62
Cela cassera en l'an 10 000.
sferik
16
@sferik: Peu importe. L'affiche originale indiquait spécifiquement qu'il voulait vérifier quatre personnages. Il n'a pas déclaré qu'il voulait que l'année 10 000 soit une entrée valide, donc accepter 10000serait un bug.
markusk
4
@sferik: Le programme sera parti pendant des siècles d'ici là. Sinon, il vaut mieux s'inquiéter de 9 000 ans dans le futur. Suivant le principe de YAGNI, l'approche est valable.
Phil
182

Années de 1000 à 2999

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

Pour 1900-2099

^(19|20)\d{2}$
r92
la source
14
C'est une bien meilleure solution
mk_89
10
Je préfère utiliser un groupe sans capture:^(?:19|20)\d{2}$
Eldar Agalarov
Comment valider une année à 4 chiffres entre 2011 et 2099?
mcquaim
Comment puis-je ajouter (19|20)\d{2}à mon regex afin de valider un format de date de naissance? Ceci est mon expression régulière /^[0-9]{1,2}\/(0[1-9])|(1[0-2])\/[0-9]{4}$/Je veux m'assurer que l'année a toujours 4 chiffres et commence par 19 ** ou 20 **
ltdev
Utilisez ^ (19 | 2 [0-9]) \ d {2} $ pour les années 1900 - 2999
MarcoZen
22

La réponse «acceptée» à cette question est à la fois incorrecte et myope.

Il est incorrect en ce sens qu'il correspondra à des chaînes comme 0001, qui n'est pas une année valide.

Il est myope en ce sens qu'il ne correspondra à aucune valeur supérieure à 9999. Avons-nous déjà oublié les leçons de l' an 2000 ? À la place, utilisez l'expression régulière:

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

Si vous avez besoin de faire correspondre des années dans le passé, en plus des années dans le futur, vous pouvez utiliser cette expression régulière pour faire correspondre tout entier positif:

^[1-9]\d*$

Même si vous ne vous attendez pas à des dates du passé, vous voudrez peut-être utiliser cette expression régulière de toute façon, juste au cas où quelqu'un inventerait une machine à remonter le temps et voudrait ramener votre logiciel avec lui.

Remarque: Cette expression régulière correspondra à toutes les années, y compris celles antérieures à l'année 1, car elles sont généralement représentées avec une désignation BC au lieu d'un entier négatif. Bien sûr, cette convention pourrait changer au cours des prochains millénaires, la meilleure option est donc de faire correspondre tout entier (positif ou négatif) avec l'expression régulière suivante:

^-?[1-9]\d*$
sferik
la source
3
Non, ce ne sera probablement pas le cas. Mais quelqu'un (archéologue? Historien?) Pourrait avoir besoin de faire correspondre des années à 8000 ans. : D Et Doc Brown pourrait en avoir besoin ...
Jaime
1
Je l'ai utilisé pour limiter la plage de 1000-9999 ^ [1-9] \\ d {3} $ c'est parce que l'application à laquelle nous devons fournir des données, n'accepte que les nombres à 4 chiffres :(
MatPag
Réponse géniale. Je ferais ce qui suit pour accepter également l'année 0: ^ (-? [1-9] \ d * | 0) $
Kosta Kontos
10

Cela fonctionne de 1900 à 2099:

/(?:(?:19|20)[0-9]{2})/
jonschlinkert
la source
me semble que cela irait seulement à 2099. BTW l'OP demande comment autoriser uniquement un nombre positif à 4 chiffres.
DeanOC
bah, 2099 c'est ce que je voulais dire. Merci. et maintenant je vois la partie des entiers positifs.
jonschlinkert
J'ai créé un projet, to-regex-range pour créer automatiquement ces plages
jonschlinkert
5

S'appuyant sur la réponse @ r92, pour les années 1970-2019:

(19[789]\d|20[01]\d)
Renaud
la source
Votre réponse le permet197999
avalanche1
Je ne pense pas que ce soit le cas ... La première partie de l'expression régulière correspond au nombre commençant par 19, puis l'un des 7,8 ou 9, suivi d'un SEUL numéro. La regex 19[789]\d\d\dpermettrait197999
Renaud
1
/(19[789]\d|20[01]\d)/.test(1970324) >> true
avalanche1
oui, il correspondra aux 4 premiers chiffres ( 1970), pas aux 3 derniers. Et (19[789]\d|20[01]\d)[^0-9]? Cela correspondrait 1970 324mais pas1970324
Renaud
1
J'ai trouvé celui-ci utile pour trouver l'année du film à partir d'un nom de fichier ... dans ce cas, nous voulons des choses à partir des années 1930 ... mais nous excluons ensuite le 1024 qui est ajouté à la fin pour la qualité vidéo
Adrian Hum
2

En théorie, l'option à 4 chiffres est correcte. Mais en pratique, il serait peut-être préférable d'avoir une plage de 1900 à 2099.

De plus, il doit s'agir d'un groupe non capturant. De nombreux commentaires et réponses proposent de capturer un regroupement qui n'est pas approprié à mon humble avis. Parce que pour la correspondance, cela peut fonctionner, mais pour extraire des correspondances à l'aide de regex, il extraira des nombres à 4 chiffres et des nombres à deux chiffres (19 et 20) également à cause de la paranthèse.

Cela fonctionnera pour une correspondance exacte en utilisant des groupes non capturants:

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

Adil Aliyev
la source
1

vous pouvez utiliser qc comme [ ^-]\d{4}$: vous évitez que le signe moins -soit avant vos 4 chiffres.
vous pouvez également utiliser ^\d{4}$avec ^pour attraper le début de la chaîne. Cela dépend de votre scénario en fait ...

PierrOz
la source
1

Pour tester une année dans une chaîne qui contient d'autres mots avec l'année, vous pouvez utiliser l'expression régulière suivante: \ b \ d {4} \ b

Dhyey
la source
C'était exactement ce dont j'avais besoin, la réponse acceptée ne semble pas être un PCRE valide.
Prometheus
0

Vous pouvez convertir votre entier en une chaîne. Comme le signe moins ne correspondra pas aux chiffres, vous n'aurez aucune année négative.

Camarade
la source
0

J'utilise cette regex en Java ^(0[1-9]|1[012])[/](0[1-9]|[12][0-9]|3[01])[/](19|[2-9][0-9])[0-9]{2}$

Œuvres de 1900 à 9999

R2Rivs
la source
0

/ ^ \ d {4} $ / Ceci vérifiera si une chaîne se compose de seulement 4 nombres. Dans ce scénario, pour entrer une année 989, vous pouvez donner 0989 à la place.

Dayz
la source
0

Si vous devez faire correspondre AAAA ou AAAAMMJJ, vous pouvez utiliser:

^((?:(?:(?:(?:(?:[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})$
Benjamin Goodacre
la source
0

Vous pouvez également utiliser celui-ci.

([0-2][0-9]|3[0-1])\/([0-1][0-2])\/(19[789]\d|20[01]\d)
Ranjeet Chouhan
la source
Ils veulent correspondre à l'année seulement. De plus, votre regex correspond à 00/00/2000ou 31/02/1999et bien d'autres fausses dates.
Toto
Cela pourrait vous aider ([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])est une bien meilleure expression pour le mois
EZ-C