RegExp Level 2
Par Cédric Tabin le jeudi 31.07.2008, 19:00 - ActionScript - Lien permanent
Grande nouveauté du langage ActionScript 3, les expressions régulières (RegExp) sont désormais supportées directement par le Flash Player. La plupart du temps, leur utilisation se borne à des cas simples, mais pour des cas plus complexes, il existe des fonctionnalités très intéressantes ! Dans mon cas, l'idée était de mettre en place une RegExp permettant de vérifier la fiabilité d'un mot de passe.
Pour qu'on mot de passe soit jugé fiable et sécurisé (toujours dans mon cas), il doit adhérer aux règles suivantes :
- doit comporter un nombre de caractères minimum (au moins 6)
- doit comporter au moins une majuscule (et une minuscule)
- doit comporter au moins un chiffre
- ne doit comporter aucun espace
ActionScript 3 fournit déjà quelques méta-caractères permettant de représenter une séquence de caractères (\s pour tous les espaces par exemple). Si on se borne aux fonctionnalités standardes, la première solution (archi-basique) serait quelque chose dans le genre :
var sample:String = "aBc09YzAui"; var pattern:RegExp = /^[a-zA-z0-9]+$/ trace(pattern.test(sample)); //true
Le souci de cette expression régulière est que l'on pourrais ne mettre que des minuscules, que des majuscules, ou même que des chiffres, cela passerait quand même. On peut donc essayer quelque chose du genre :
var sample:String = "aBc09YzAui"; var pattern:RegExp = /^[a-z]+[A-Z]+[0-9]+$/ trace(pattern.test(sample)); //false
Cette fois, il est obligatoire d'avoir au moins une minuscule, au moins une majuscule et au moins un chiffre. Deux problèmes avec cette RegExp : l'ordre est déterminé (au moins une minuscule suivie d'au moins une majuscule suivie d'un ou plusieurs chiffres) et que l'on n'a pas pu mettre un longueur de chaîne minimale...
Une solution du type (pour faire en sorte qu'il y ait au moins 6 caractères)
var pattern:RegExp = /^([a-z]+[A-Z]+[0-9]+){6,}$/
ne marche pas non plus, car l'ordre est toujours nécessaire (par exemple aA0bB1 marcherait, tandis que a01BbA ne passerait pas). Afin de pouvoir checker cela en une RegExp, il faut avoir une autre manière de faire.
Et c'est là ou interviennent les lookahead groups ! Ce mécanisme permet de définire une "sous-requete" RegExp de la même manière qu'une suite de conditions. Petit exemple rapide :
var pattern:RegExp = /sh(?=e)(\w*)/i; var str:String = "Shelly sells seashells by the seashore"; trace(pattern.test(str)); //true
Dans le cas ci-dessus, on veut une chaîne commencant par 'sh' suivi de n'importe quelle suite de caractères visibles dont le premier est un 'e' (le tout avec l'option ignore case).
Cette idée appliquée à mon cas initiale nous donne :
var sample:String = "aBc09YzAui"; var pattern:RegExp = /^(?=.*[a-z]+)(?=.*[A-Z]+)(?=.*[0-9]+)([^\s]{6,})$/ trace(pattern.test(sample)); //true
Toutes les contraintes sont respectées :
- [^\s]{6,} indique qu'il faut une chaine d'au moins 6 caractères ne contenant pas d'espace, tabulation ou retour de ligne
- (?=.*[0-9]+) indique que dans la chaîne (1), il y ait au moins un ou plusieurs chiffres
- (?=.*[A-Z]+) indique que dans la chaîne (1), il y ait au moins une ou plusieurs majuscules
- (?=.*[a-z]+) indique que dans la chaîne (1), il y ait au moins une au plusieurs minuscules
A noter qu'il existe aussi l'inverse de (?=X) se notant (?!X) qui se traduit par 'dont la sous-requête n'est pas égale à' ! Cela permet vraiment de pouvoir faire beaucoup de chose, même très compliquée. Il existe même des sites comme regexlib qui permettent de trouver plein d'expressions régulières dont certaines sont particulièrement méchantes (et inutile :D).
PS. Pour ceux qui cherchent le billet 'RegExp Level 1' il n'existe pas !
Commentaires
question bête, mais : c'est quoi le problème avec un espace dans un mot de passe ?
Salut,
Ca peut être pour des raisons de parsing, un espace étant souvent considéré comme séparateur. Dans un mot de passe qui sera encrypté, c'est vrai que ce n'est pas vraiment un problème...
@++
j'utilise tres peu les expressions regulieres mais il est vrai que c'est tres puissant. Il faut vraiment que je m'y penche plus.
En ce qui concerne les mot de passe, J'utilise un mot de passe dans cette esprit pour mon cas personnel mais je ne fais pas de tels tests car mes applis sont destinées au grand public. Je sais bien que ceci n'est pas très sécurisé mais de tels mot de passe sont un frein pour l'utilisateur lambda. En fait tout dépend de l'appli que l'on fait.
Toujours utile, les expressions régulières, et aussi pratique à utiliser
Bonjour ou bonsoir,
J'aimerai savoir si c'est aussi possible d'obliger à mettre un mot définit à l'avance dans un chmap de formulaire.
Par exemple poser la question: quelle est la capitale de la France
et si le visiteur ne répond pas Paris ou autre chose (merci les robots GRRR) le formulaire n'est pas envoyé et un message indique qu'il s'agit d'une erreur.
Merci d'avance pour votre réponse
Salut,
Heu je comprends mal ta question... Il suffit de faire une RegExp simple non ? Pas besoin d'avoir de lookahead groups ou autre. Il te faudra juste faire le check coté serveur pour éviter les tentatives de hack
@++
Bon je précise ma question, en collant un bout de mon script
Pour une adresse email j'ai ce script :
var email = document.formulaire.email.value;
j'aimerai la même chose pour un mot définit alors j'ai essayé comme ça:
var email = document.formulaire.email.value;
Mais ça ne fonctionne qu'à moitié parce qu'il me redemande chaque fois d'inscrire Paris.
Suis-je plus clair?
Je guette avec impatience la réponse
Merci d'avance
Re,
Oui c'est normal car l'opérateur '^' signifie 'début de phrase' et '$' signifie 'fin de phrase'. Essaie simplement avec /Paris/ ou alors /.*Paris.*/ !
@++
Super ça marche avec /Paris/
merci mille fois.
Peux-tu me dire la différence entre /Paris/ et /.*Paris.*/
J'en profite alors, vu que tu es au top toi, de te demander aussi le code pour n'inscrire que des chiffres dans le champ Code Postal.
Mais rien n'urge parce que là je vais (enfin) me coucher
Alors bonne nuit à toi aussi
Salut,
Dans ton cas, aucune différence, ça dépend surtout de la fonction que tu utilises. Dans le cas d'un search, les deux sont équivalant, mais pas dans le cas d'un matches ('.' signifie 'n'importe quel caractère' et '*' veut dire '0 ou plusieurs fois').
Pour le code postal, tu peux utiliser un truc du genre /0-9{4}/ => Il doit avoir un chiffre (de 0 à 9) 4 fois. Tu peux remplacer le '{4}' par un '+' si tu veux juste dire 'au moins un chiffre' ou alors par '{4,}' pour dire 4 chiffres ou plus
@++