La véritable force des expressions régulières réside dans les possibilités qu'elles offrent pour constituer des modèles de recherche très généraux, dans lesquelles les chaînes recherchées n'ont pas besoin d'être définies précisément, mais peuvent plutôt être décrites comme des suites de caractères acceptables, dont les répétitions peuvent être laissées libres (un chiffre de 1 à 9999 par exemple) ou au contraire fixées car connues et devant répondre à un masque bien particulier (une adresse email par exemple).
Des régles de répétition de caractères, ou de groupes de caractères, permettent ainsi d'écrire à partir de modèles simples des expressions régulières complexes. Les modèles ainsi définis étendent les capacités de recherche et de substitution à un grand nombre de cas et de chaînes.

### Répétitions fixées de caractères

Les accolades ouvrantes et fermantes ({ et }) permettent de définir la répétition de caractères, de classes ou de modèles.

Par exemple, l'expression régulière /il{2}/ recherchera un i suivi de 2 l. Elle sera vraie pour "Djedaille", et fausse pour "il".

Pour tester qu'un code postal français est correct, l'expression régulière peut être /\d{5}/,
équivalente à /[[:digit:]]{5}/,
équivalente à /[0-9]{5}/.

Pour tester qu'une date qu'une date est formatée suivant le modèle JJ/MM/AAAA, l'expression régulière sera /\d{2}\/\d{2}\/\d{4}/ (je vous laisse trouver les équivalences).
Notez le backslash (\) de protection devant les slash (/) séparant le jour, le mois et l'année.

Exemple : répétitions fixées de caractères
<?php require('bib_fonctions.php'); htmlDebut('Répétitions fixées'); $txt = "il y a bien longtemps, dans une très lointaine galaxie (36éme lune à gauche après le Djedaille's Bar)..."; htmlInfo('Recherche "ill"'); testerExp('/il{2}/', $txt); htmlInfo('Recherche les voyelles doublées'); testerExp('/[aeiou]{2}/', $txt); htmlInfo('Recherche 5 chiffres consécutifs'); $txt = '1234 12345 12b45 12,345 12.345 '; testerExp('/\d{5}/', $txt); htmlFin(); ?>

### Exercice : vérifier le format d'un numéro de carte bancaire

Les numéros de cartes bancaires sont constitués par un préfixe indiquant le type de carte, suivi d'un nombre variable de chiffres.

Type de carte | Préfixe | Nombre total de chiffres
MasterCard | de 51 à 55 | 16
Visa | 4 | 13 ou 16
AMEX | 34 ou 37 | 15
DinnersClub | de 300 à 305, ou 36 ou 38 | 14
Discover | 6011 | 16
enRoute | 2014 ou 2149 | 15
JCB | 3 | 16
2131 ou 1800 | 15

Votre mission si vous l'acceptez, n'est pas de créer des faux numéros de cartes bancaires, mais d'écrire une expression régulière par type de carte qui permette de vérifier que le numéro donné est correcte par rapport au format attendu.

Pour vous aider ...

Si on imagine que le numéro de carte a été saisi par l'utilisateur au travers d'une zone de formulaire, il peut être précédé et/ou suivi d'espaces ou d'autres caractères. Il nous faut donc d'abord être sûr que le numéro que nous testons n'est pas "pollué" par d'autres caractères.
Nous devons donc constuire une régle qui définit que la valeur à tester commence obligatoirement par certains caractères, et se termine obligatoirement par certains autres caractères.

On spécifie qu'une chaîne doit commencer par un caractère précis avec le métacaractère ^.
Par exemple /^a/ indique que la chaîne à tester doit commencer obligatoirement par a.

On spécifie qu'une chaîne doit finir par un caractère précis avec le métacaractère $ .
Par exemple /z$/ indique que la chaîne à tester doit se terminer obligatoirement par z.

Ainsi l'expression régulière /^\d{10}$/ indique que la chaîne à tester doit se composer d'un nombre de dix chiffres, ni plus, ni moins, et à l'exclusion de tout caractère non numérique.

L'expression régulière pour tester le format d'une carte de type Discover sera donc : /^6011\d{12}$/
^6011 indique que le numéro doit commencer par 6011
\d{12}$ indique que le numéro doit se terminer par 12 chiffres.

Une solution possible

Exercice : tester un numéro de carte bancaire
<?php require('bib_fonctions.php'); htmlDebut('Tester un numéro de carte bancaire'); //------------------------------------------------ htmlInfo('MASTERCARD'); echo 'Préfixe de 51 à 55, suivi de 14 chiffres'; $expression = '/^5[1-5]\d{14}$/'; $numeroCarte = '5212345678901234'; testerExp($expression, $numeroCarte); $numeroCarte = '5612345678901234'; testerExp($expression, $numeroCarte); //------------------------------------------------ htmlInfo('VISA'); echo 'Préfixe 4, suivi de 12 ou 15 chiffres'; $expression = '/^4\d{12}$|^4\d{15}$/'; $numeroCarte = '4123456789012345'; testerExp($expression, $numeroCarte); $numeroCarte = '412345678901'; testerExp($expression, $numeroCarte); //------------------------------------------------ htmlInfo('AMEX'); echo 'Préfixe de 34 ou 37, suivi de 13 chiffres'; $expression = '/^3[47]\d{13}$/'; $numeroCarte = '371234567890123'; testerExp($expression, $numeroCarte); $numeroCarte = '361234567890123'; testerExp($expression, $numeroCarte); //------------------------------------------------ htmlInfo('DINNERS'); echo 'Préfixe de 300 à 305, suivi de 11 chiffres<br>', 'ou préfixe 36 ou 36, suivi de 12 chiffres'; $expression = '/^30[0-5]\d{11}$|^3[68]\d{12}$/'; $numeroCarte = '30212345678901'; testerExp($expression, $numeroCarte); $numeroCarte = '30712345678901'; testerExp($expression, $numeroCarte); //------------------------------------------------ htmlInfo('DISCOVER'); echo 'Préfixe 6011, suivi de 12 chiffres'; $expression = '/^6011\d{12}$/'; $numeroCarte = '6011123456789012'; testerExp($expression, $numeroCarte); $numeroCarte = '601112345678901'; testerExp($expression, $numeroCarte); //------------------------------------------------ htmlInfo('ENROUTE'); echo 'Préfixe 2014 ou 2149, suivi de 11 chiffres'; $expression = '/^2014\d{11}$|^2149\d{11}$/'; $numeroCarte = '201412345678901'; testerExp($expression, $numeroCarte); $numeroCarte = '205012345678901'; testerExp($expression, $numeroCarte); //------------------------------------------------ htmlInfo('JCB'); echo 'Préfixe 3, suivi de 15 chiffres<br>', 'ou préfixe 2131 ou 1800, suivi de 11 chiffres'; $expression = '/^3\d{15}$|^2131\d{11}$|^1800\d{11}$/'; $numeroCarte = '180012345678901'; testerExp($expression, $numeroCarte); $numeroCarte = '2123456789012345'; testerExp($expression, $numeroCarte); htmlFin(); ?>