Comment rendre ses expressions rationnelles lisibles et maintenables
Comment écrire plus facilement des expressions rationnelles (ou régulières)
Une expression rationnelle est souvent un truc (oui, truc) moche et complètement illisible. Pour pallier à cela, réfléchissez à la manière dont vous voulez construire une expression rationnelle. Et n'hésitez pas à la construire sur plusieurs lignes, et même de la documenter.
Pour ce faire, deux solutions existent : la première est de créer son expression comme une concaténation de plusieurs chaînes ; la seconde est l'utilisation du flag COMMENT (ou x, en perl).
Voyons voir une expression rationnelle qui à première vue est illisible :
Code:
Pattern regex = Pattern.compile("^((?:ht|f)tps?)://((?:\\p{Alpha}(?:-?\\w+)*\\.)*\\p{Alpha}\\w*|(?:\\d+\\.){3}\\d+)(?::(\\d{1,5}))?/");
La première solution serait de l'écrire comme ceci :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Pattern regex = Pattern.compile(
"^" // Début de ligne
+ "((?:ht|f)tps?)" // Récupération du protocole : http, https, ftp ou ftps, on oublie le groupe formé par ht|f.
+ "://" // séparateur protocole - hôte.
+ "(" // Nous désirons capturer le nom d'hôte dans son intégralité.
+ "(?:\\p{Alpha}(?:-?\\w+)*\\.)*" // Un nom d'hôte est formé d'une lettre, suivi d'un tiret facultatif et pour chaque tiret, il doit être suivi d'un caractère autre qu'un tiret.
+ "\\p{Alpha}\\w*" // La dernière partie du nom d'hôte ne peut comporter que des caractères alphanumériques, avec une lettre en première position.
+ "|" // ou alors une adresse IP
+ "(?:\d+\.){3}" // Une adresse IP v4 est formée de chiffres suivis d'un point, 3 fois
+ "\d+" // et se termine par des chiffres.
+ ")" // Fin de la capture du nom d'hôte.
+ "(?::(\d{1,5}))?" // S'il y a un port, on le récupère également dans son propre groupe. On évite soigneusement de récupérer le "deux-points".
+ "/" // Fin de l'expression rationnelle liée à une URL.
); |
La deuxième solution est d'utiliser des commentaires directement dans l'expression.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Pattern regex = Pattern.compile("
^ # Début de ligne
((?:ht|f)tps?) # Récupération du protocole : http, https, ftp ou ftps, on oublie le groupe formé par ht|f.
:// # séparateur protocole - hôte.
( # Nous désirons capturer le nom d'hôte dans son intégralité.
(?:\\p{Alpha}(?:-?\\w+)*\\.)* # Un nom d'hôte est formé d'une lettre, suivi d'un tiret facultatif et pour chaque tiret, il doit être suivi d'un caractère autre qu'un tiret.
\p{Alpha}\w* # La dernière partie du nom d'hôte ne peut comporter que des caractères alphanumériques, avec une lettre en première position.
| # ou alors une adresse IP
(?:\d+\.){3} # Une adresse IP v4 est formée de chiffres suivis d'un point, 3 fois
\d+ # et se termine par des chiffres.
) # Fin de la capture du nom d'hôte.
(?::(\d{1,5}))? # S'il y a un port, on le récupère également dans son propre groupe. On évite soigneusement de récupérer le "deux-points".
/ # Fin de l'expression rationnelle liée à une URL.
", Pattern.COMMENT); |
Comme vous pourrez le constater, les trois expressions présentées ici sont parfaitement identiques, mais les deux dernières sont bien plus lisibles.
Attention, certains EDI, dont Eclipse, ne supportent pas les les chaînes sur plusieurs lignes comme montrée dans le troisième exemple.