N.B. : les exemples proposés dans cet article sont en PHP, mais transposable dans la majorité des langages qui utilisent des expressions régulières compatibles Perl (PCRE).
Les groupes de capture, dans les expressions régulières, servent typiquement à faire des replacements. Par exemple pour inverser les noms et prénoms dans une liste, on réalise deux captures (nom et prénom) que l'on référence par leur numéro respectifs (\1 et \2) dans la chaîne de substitution.
<?php
// Exemple 1
// Inversion d'un nom et d'un prénom
$chaine = <<<FIN
Dupont, Marcel
Laforêt, Hugo
Lemoine, Jean-Marc
FIN;
echo preg_replace('/^(.*),\s(.*?)\r?$/m', '\2 \1', $chaine);
/*
Résultat :
Marcel Dupont
Hugo Laforêt
Jean-Marc Lemoine
*/
?>
Les groupes de capture ont une deuxième utilisation, souvent ignorée, lorsqu'ils sont référencés directement au sein de l'expression régulière. En effet, imaginons que l'on cherche toutes les adresses des images d'une page. En français, cela se traduit par :
- je cherche tout ce qui commence par
scr= ;
- suivi d'un guillemet ou d'une apostrophe ;
- suivi d'une adress ;
- puis de nouveau d'un guillemet ou d'une apostrophe (mais nécessairement le même caractère que précédemment).
Pour traduire la nécessité d'encadrer l'adresse par deux apostrophe ou deux guillemets (mais pas un mélange), il est possible d'écrire deux fois l'expression régulière (une pour chaque cas), mais une solution plus propre consiste à utiliser la référence de la capture directement dans l'expression régulière (et non la chaine de substitution). Cela donne :
<?php
// Exemple 2
// Recherche adresses images dans une page
$src = <<<HTML
<img src="test_guillemet.png" alt="" />
<img src='test_apostrophe.png' alt='' />
HTML;
preg_match_all('/src=(["\'])(.*?)\1/mi', $src, $matches);
foreach ( $matches[2] as $url ) {
echo $url;
}
/*
Résultat :
test_guillemet.png
test_apostrophe.png
*/
?>
Notez enfin qu'il est possible de donner un nom aux captures pour rendre le code plus lisible et plus robuste. Une capture s'écrit alors (?P<nom>…) et on la référence en utilisant (?P=nom). L'exemple ci-dessus s'écrirait alors :
<?php
// Exemple 3
// Recherche adresses images dans une page
// avec groupes de capture nommés
$src = <<<HTML
<img src="test_guillemet.png" alt="" />
<img src='test_apostrophe.png' alt='' />
HTML;
preg_match_all(
'/src=(?<delimiteur>["\'])(?P<url>.*?)(?P=delimiteur)/mi',
$src, $matches
);
foreach ( $matches['url'] as $url ) {
echo $url;
}
/*
Résultat :
test_guillemet.png
test_apostrophe.png
*/
?>
Voilà. N'hésitez pas à utiliser les commentaires pour réagir, signaler une erreur ou poser une question. Pour en apprendre plus sur les expressions régulières, je vous recommande fortement le site regular-expressions.info. Ne négligez pas cet outil formidablement puissant !
Derniers commentaires