2010-09-18 3 views
1

Je viens d'hériter d'un projet avec beaucoup de validation côté client. Dans ce cas, j'ai trouvé un vérificateur d'expressions rationnelles, comme prévu sans un commentaire en vue. J'admets que regex est définitivement l'un de mes points faibles. (En JavaScript!)Comment fonctionne cette fois Regex?

var myRegxp = /(([0]*[1-9]{1})|([1]{1}[0-2]{1}))(\/{1})((19[0-9]{2})|([2-9]{1}[0-9]{3}))$/; 
if (!myRegxp.test(args.Value)) 
{//do fail stuff here}; 

Je suis assez sûr du reste de la page qu'il est censé être vérifier pour une sorte de format de date. Cela passerait-il MM/AAAA? De certains tests précoces, il presque le fait.

Si cette expression rationnelle ne correspond pas à MM/YYYY, quelle serait la meilleure façon de procéder?

Un conseil des maîtres regex serait apprécié.

+2

En note: '[1-9] {1}' est équivalent à '[1-9]'. Ce dernier est préféré (par beaucoup) parce qu'il encombre moins la regex. La même chose vaut pour '[0] *' étant équivalent à '0 *' et '[1] {1}' est juste '1'. –

+0

Enfin, l'OR logique, '|', a une priorité très faible. En d'autres termes, vous n'avez pas besoin d'entourer 'AA' et' BB' entre parenthèses dans ce cas: '((AA) | (BB)) CC'. Vous pouvez simplement faire: '(AA | BB) CC'.Cela, et mes remarques précédentes, faites votre regex actuelle: '(([0] * [1-9] {1}) | ([1] {1} [0-2] {1})) (\/{ 1}) ((19 [0-9] {2}) | ([2-9] {1} [0-9] {3})) $ 'exactement la même chose que' (0 * [1-9] | 1 [0-2]) \/(19 [0-9] {2} | [2-9] [0-9] {3}) $ ' –

+0

Grande note chez Bart K. +1 – Kamal

Répondre

4

Il doit se terminer par MM/AAAA (où MM est 1-12 et AAAA est 1900-9999)

(mois correspondant)

([0]*[1-9]{1}) 
zero or more occurences of '0', and one occurence of 1-9 
Example match: 01 

OU

([1]{1}[0-2]{1}) 
1 match of '1', 1 match of 0-2 
Example match: 10 

Deuxième partie (année), d'abord il correspond littéralement à '/' avec:

(\/{1}) 

Puis l'année:

((19[0-9]{2}) 
One match of '/', 19 and two matches of 0-9 (looks like a year in the range 1900-1999) 
Example match: 1900 

OU

([2-9]{1}[0-9]{3}) 
1 match of 2-9 and thee matches of 0-9 (looks like a year in the range 2000-9999 
Example match: 2000 

A RE simplifiée:

var myRegExp = /^(0[1-9]|1[0-2])\/(19\d{2}|[2-9]\d{3})$/; 

Note: \d est une classe de caractères pour 0-9. J'ai supprimé les parenthèses utilisées pour le regroupement car elles ne sont pas utilisées dans myRegExp.test. Remplacé [0]* par 0? car il ne devrait pas correspondre 0000001/2010, mais il devrait correspondre 1/2010. Remplacé [0]* par 0 car il doit correspondre littéralement 01 et non 1. Les ^ et $ sont des ancres, ce qui les fait correspondre du début à la fin. Lorsque vous les omettez, cette RE correspond à tout texte contenant MM/AAAA.

+0

En d'autres termes pour @Kamal: Il vérifie si une certaine chaîne est une notation MONTH/YEAR. –

+0

Bonne explication. Je vous remercie. Traîner à travers le backend, c'est en effet une validation MM/YYYY. Mais il permet des valeurs jusqu'à 19 pour le mois. D'après votre explication, il est clair qu'il ne devrait pas permettre cela? – Kamal

+0

Oups, j'ai raté un groupement. Mise à jour ma réponse – Lekensteyn

1

Je suis d'accord - c'est la vérification des dates dans le format MM/yyyy.

Il autorise un nombre quelconque de zéros en début de mois. Il permet des années correspondant à 19 xx ou toute autre chose commençant par un chiffre compris entre 2 et 9 inclusivement. Cela signifie qu'il permet tout jusqu'à 9999 pour l'année :)

+1

Ce programme ne survivra probablement pas avant le 12/9999: D: D: D Ou il y aura un problème Y10k avec ce programme particulier. –

+0

Excellentes réponses les gars. Je suis sûr que quelque part dans ma lignée viendra un jour où un codeur maudira son grand-père xx pour ne pas être un penseur avant. – Kamal

Questions connexes