Gruppi di acquisizione nelle espressioni regolari in PHP
Il contenuto dei gruppi di acquisizione non è disponibile solo nella stringa di sostituzione, ma anche nell'espressione regolare stessa: noi possiamo mettere qualcosa in un gruppo, e poi dire direttamente nell'espressione regolare che qui deve essere presente il contenuto di quel gruppo.
Il contenuto dei gruppi di acquisizione è accessibile tramite i loro numeri,
preceduti da una barra rovesciata. Per esempio,
il gruppo zero sarà accessibile così: \0,
il primo gruppo così - \1, il secondo
- \2 e così via.
Sono sicuro che tutto quanto scritto sopra sia ancora piuttosto oscuro per te. Non è sorprendente, dato che i gruppi di acquisizione sono l'argomento più difficile da capire delle espressioni regolari. Analizziamolo con degli esempi.
Esempio
Supponiamo di avere una stringa come questa:
<?php
$str = 'aa bb cd ef';
?>
Troviamo in essa tutti i punti in cui ci sono due lettere qualsiasi uguali consecutive. Per risolvere il problema, cercheremo qualsiasi lettera, la metteremo in un gruppo, e poi controlleremo se il carattere successivo è il contenuto di quel gruppo:
<?php
$res = preg_replace('#([a-z])\1#', '!', $str);
?>
Di conseguenza, nella variabile verrà memorizzato quanto segue:
'! ! cd ef'
Esempio
Supponiamo di avere una stringa come questa:
<?php
$str = 'asxca buzxb csgd';
?>
Troviamo in essa tutte le parole in cui la prima e l'ultima lettera sono uguali. Per risolvere il problema, scriveremo il seguente schema: una lettera, poi una o più lettere, e poi la stessa lettera della prima:
<?php
$res = preg_replace('#([a-z])[a-z]+\1#', '!', $str);
?>
Di conseguenza, nella variabile verrà memorizzato quanto segue:
'! ! csgd'
Esempio
Invece di \1 si può scrivere \g1:
<?php
$res = preg_replace('#([a-z])[a-z]+\g1#', '!', $str);
?>
Esempio
Si può anche scrivere \g{1}:
<?php
$res = preg_replace('#([a-z])[a-z]+\g{1}#', '!', $str);
?>
Esempio
Nelle parentesi graffe si possono indicare numeri negativi. In questo caso i gruppi verranno contati dalla fine:
<?php
$res = preg_replace('#([a-z])([a-z])\g{-2}#', '!', $str);
?>
Problemi pratici
Data una stringa:
<?php
$str = 'aaa bbb ccc xyz';
?>
Trova tutte le sottostringhe in cui ci sono tre lettere uguali consecutive.
Data una stringa:
<?php
$str = 'a aa aaa abab bbbb';
?>
Trova tutte le sottostringhe in cui ci sono due o più lettere uguali consecutive.
Data una stringa:
<?php
$str = 'aaa aaa bbb bbb ccc ddd';
?>
Trova tutte le sottostringhe in cui ci sono due parole uguali consecutive.