preg_replace_callback
In PHP, preg_replace_callback() esegue ricerca e sostituzione tramite espressioni regolari usando una funzione di callback per ogni corrispondenza.
Introduzione
preg_replace_callback() esegue una ricerca e sostituzione con espressioni regolari, ma invece di fornire una stringa di sostituzione fissa, le si passa una funzione di callback che viene eseguita per ogni corrispondenza. Il callback riceve la corrispondenza (e i gruppi di cattura) e restituisce il testo da sostituire. Questo consente di calcolare le sostituzioni con vera logica PHP — mettere in maiuscolo una parola, aggiungere 1 a un numero, cercare un valore in una tabella — cosa che la semplice funzione preg_replace() non può fare.
Usala ogni volta che la sostituzione dipende da cosa è stato trovato. Se la sostituzione è una costante o un semplice riferimento come $1, usa preg_replace(); se hai bisogno di un callback diverso per ogni pattern, vedi preg_replace_callback_array().
Sintassi
preg_replace_callback(
string|array $pattern,
callable $callback,
string|array $subject,
int $limit = -1,
int &$count = null,
int $flags = 0
): string|array|null| Parametro | Descrizione |
|---|---|
$pattern | L'espressione regolare (una stringa delimitata) da trovare, o un array di pattern. |
$callback | Un callable eseguito per ogni corrispondenza. Riceve l'array delle corrispondenze e restituisce la stringa di sostituzione. |
$subject | La stringa (o array di stringhe) in cui cercare e modificare. |
$limit | Numero massimo di sostituzioni per stringa soggetto. -1 (valore predefinito) significa nessun limite. |
$count | Passato per riferimento; viene riempito con il numero di sostituzioni effettuate. |
$flags | PREG_OFFSET_CAPTURE e/o PREG_UNMATCHED_AS_NULL, che rispecchiano preg_match(). |
Restituisce il soggetto modificato, o null se si verifica un errore regex. Il primo argomento del callback è l'array $matches: $matches[0] è l'intera corrispondenza e $matches[1], $matches[2], … sono i gruppi catturati — esattamente come l'array riempito da preg_match().
Esempio base: maiuscolo per ogni parola
Il pattern \w+ trova ogni sequenza di caratteri di parola. Per ogni corrispondenza il callback riceve $matches[0] (la parola) e restituisce la sua forma maiuscola, che viene reinserita nella stringa.
Lavorare con i gruppi di cattura
Le parentesi nel pattern creano gruppi di cattura che appaiono in $matches[1], $matches[2] e così via. Qui aggiungiamo uno a ogni numero in una stringa:
<?php
$subject = 'Room 12, floor 3, building 7';
$result = preg_replace_callback('/(\d+)/', function ($m) {
return (string) ((int) $m[1] + 1);
}, $subject);
echo $result;
// Room 13, floor 4, building 8Poiché il callback esegue codice reale, l'incremento viene calcolato per ogni corrispondenza — qualcosa che una stringa di sostituzione statica non può mai esprimere.
Un caso d'uso pratico: mascherare dati sensibili
Un'operazione comune è nascondere parzialmente email o numeri di carta nei log. Il callback può decidere quanta parte di ogni corrispondenza rivelare:
<?php
$text = 'Contact: [email protected] or [email protected]';
$result = preg_replace_callback('/([\w.]+)@([\w.]+)/', function ($m) {
$name = $m[1];
$masked = $name[0] . str_repeat('*', max(strlen($name) - 1, 1));
return $masked . '@' . $m[2];
}, $text);
echo $result;
// Contact: a****@example.com or b**@test.orgContare e limitare le sostituzioni
I parametri $limit e $count consentono di limitare quante corrispondenze vengono elaborate e di sapere quante lo sono state effettivamente:
<?php
$subject = 'a a a a a';
$result = preg_replace_callback('/a/', function ($m) {
return 'b';
}, $subject, 2, $count);
echo $result, "\n"; // b b a a a
echo $count; // 2Solo le prime due a vengono sostituite perché $limit è 2, e $count riporta il numero di sostituzioni effettuate.
preg_replace vs. preg_replace_callback
| Utilizzo | Funzione |
|---|---|
Testo fisso o un riferimento come $1 | preg_replace() |
| Sostituzione calcolata dalla corrispondenza | preg_replace_callback() |
| Un callback diverso per ogni pattern | preg_replace_callback_array() |
Per trovare corrispondenze senza sostituire, vedi preg_match() e preg_match_all(), e il capitolo sulle espressioni regolari PHP per la sintassi dei pattern.
Errori comuni
- Restituire sempre una stringa. Il valore di ritorno del callback viene convertito in stringa e inserito. Restituire
nullrimuove la corrispondenza; dimenticare ilreturninserisce una stringa vuota. - Fare riferimento all'indice corretto.
$matches[0]è la corrispondenza completa; il gruppo 1 si trova in$matches[1]. L'errore off-by-one qui è il bug più frequente. - Fare attenzione all'escaping. A differenza di
preg_replace(), nel risultato non si scrivono riferimenti$1/\1— si costruisce la stringa manualmente, quindi non c'è nulla da fare l'escape nella sostituzione. - Un valore
nullrestituito dalla funzione stessa (non dal callback) segnala un errore regex, come un delimitatore senza corrispondenza.
Conclusione
preg_replace_callback() è lo strumento giusto ogni volta che una sostituzione deve essere calcolata piuttosto che specificata. Combina la potenza di ricerca delle espressioni regolari con logica PHP arbitraria nel callback, rendendola ideale per trasformare, mascherare o ricalcolare il testo trovato. Per sostituzioni statiche usa preg_replace(), e per più pattern contemporaneamente usa preg_replace_callback_array().