Dans certains cas nous ne voulons pas capturer toutes les chaînes entre parenthèses, mais les parenthèses sont néanmoins nécessaires dans la syntaxe de l'expression.
Soit le texte :
"Il y a bien longtemps, dans une
galaxie lointaine, l'Empire Impérial de l'Empereur triomphe sur
tous les fronts, broyant tous ceux qui s'opposent à lui d'une main
de fer dans un gant d'acier. Seul un petit groupe de rebelles se
bat toujours pour la liberté face à la tyrannie, pour le chaos face
à l'ordre, et d'abord on fait c'qu'on veut merde !"
Si nous voulons récupèrer tous les mots qui suivent le, la, les, un,
une et des, nous aurons l'expression :
\b(le|la|les|un|une|des)\s(\w+)\b
Ici, il vaut mieux utiliser la constante prédéfinie PREG_PATTERN_ORDER que la constante PREG_SET_ORDER
L'expression fonctionne, mais nous avons capturé aussi les pronoms
alors que nous voulons seulement le mot qui les suit. Ici encore,
comme avec les quantificateurs, nous pouvons rendre les parenthèses
non gourmandes, ou non capturantes, en ajoutant simplement ?: après la parenthèse ouvrante :
\b(?:le|la|les|un|une|des)\s(\w+)\b
La capture avec des parenthèses est une capture mémorisante :
l'expression capturée est gardée en mémoire par le moteur
d'expressions régulières et pourra servir à nouveau dans la
suite de l'expression.
On appelle cela une référence
arrière, notée par un backslash, suivi du numéro de la capture
correspondante (ie \1, \2, etc.) .
Un des exemples typiques du fonctionnement des références arrières
consiste à rechercher si une chaîne contient le même mot répété 2
fois de suite. Pour rechercher un mot nous aurons l'expression
régulière suivante :
\b(w+)\s+
Soit un début de mot (\b), suivi de 1
ou plusieurs caractères de mot (w+),
suivi de 1 ou plusieurs caractères d'espacement (\s+). Les parenthèses autour de w+
permettent de capturer le mot trouvé. En ajoutant \1 après l'expression, vous pouvons
référencer cette capture :
\b(w+)\s+\1
Ne pas mettre de quatrième argument à la fonction preg_match_all()équivaut à utiliser PREG_PATTERN_ORDER
L'exemple suivant permet d'extraire d'une partie de code HTML tous
les textes entourés par les tags <b> ou <i> avec
l'expression :
<([bi])>(.*?)</\1>
<([bi])> recherche les chaînes comme <b> et <i>, et capture le b ou le i, que nous réutilisons pour définir la balise fermante : </\1>
Comme cette expression contient un /, nous utiliserons le caractère # comme délimiteur de l'expression régulière.
Pendant que nous sommes dans les tags HTML, voilà l'expression
régulière qui permet de capturer tous les tags HTML, qu'ils aient ou
non des attributs :
<\s*?(\w+)\b.*?>
Pour extraire les textes entourés par n'importe quel tag HTML, nous
aurons l'expression :
<\s*?(\w+)\b.*?>(.*?)</\1>
Attention, dans le cas de tags imbriqués, cette expression ne capturera que le tag le plus profond dans l'imbrication.