preg_match_all()
In PHP, preg_match_all() esegue una ricerca globale con espressioni regolari e restituisce tutte le occorrenze di un pattern in una stringa.
Introduzione
In PHP, le espressioni regolari sono fondamentali per cercare e manipolare stringhe. Mentre preg_match() si ferma alla prima corrispondenza, preg_match_all() continua la scansione e restituisce ogni occorrenza di un pattern in una stringa. Usala ogni volta che hai bisogno di estrarre tutti i numeri di telefono, tutti i tag, tutte le parole o qualsiasi struttura ripetuta da un testo.
Questo articolo spiega la sintassi, il fondamentale argomento $flags che controlla come vengono organizzati i risultati e diversi esempi pratici.
Sintassi
preg_match_all(
string $pattern,
string $subject,
array &$matches = null,
int $flags = PREG_PATTERN_ORDER,
int $offset = 0
): int|false$pattern— l'espressione regolare, delimitata da/.../(o qualsiasi delimitatore corrispondente).$subject— la stringa in cui cercare.$matches— un array di output (passato per riferimento) riempito con tutte le corrispondenze trovate.$flags— opzionale. Controlla come è strutturato$matches(vedi sotto).$offset— opzionale. Offset in byte in$subjectda cui iniziare la ricerca.
Restituisce il numero di corrispondenze complete del pattern (che può essere 0), oppure false se il pattern non è valido.
Una semplice corrispondenza
L'utilizzo più semplice è raccogliere ogni sottostringa che corrisponde a un pattern. Qui estraiamo tutti i numeri da una frase:
<?php
$subject = 'Room 12, floor 3, building 7';
$count = preg_match_all('/\d+/', $subject, $matches);
echo "Found $count numbers\n";
print_r($matches[0]);Output:
Found 3 numbers
Array
(
[0] => 12
[1] => 3
[2] => 7
)Quando il pattern non ha gruppi di cattura, $matches[0] contiene l'elenco delle corrispondenze complete.
Scegliere un flag: PREG_PATTERN_ORDER vs PREG_SET_ORDER
L'argomento $flags determina come vengono organizzate le corrispondenze e i gruppi di cattura. I due flag principali si escludono a vicenda:
PREG_PATTERN_ORDER(il valore predefinito) —$matches[0]contiene tutte le corrispondenze complete,$matches[1]tutte le catture del gruppo 1,$matches[2]tutte le catture del gruppo 2, e così via. Pensalo come "colonna per colonna".PREG_SET_ORDER—$matches[0]è la prima corrispondenza completa (corrispondenza completa + i suoi gruppi),$matches[1]è la seconda, e così via. Pensalo come "riga per riga".
Puoi anche aggiungere PREG_OFFSET_CAPTURE per registrare l'offset in byte di ogni corrispondenza insieme al suo testo.
PREG_SET_ORDER (raggruppa i risultati per occorrenza)
Questo layout è il più semplice da iterare quando ogni corrispondenza ha più gruppi di cattura:
Output:
Name: Alice, Age: 25
Name: Bob, Age: 30Con PREG_SET_ORDER, ogni $match è un'occorrenza: $match[0] è la corrispondenza completa, $match[1] è il primo gruppo (nome), $match[2] è il secondo gruppo (età).
PREG_PATTERN_ORDER (raggruppa i risultati per pattern)
Lo stesso pattern con il flag predefinito restituisce i gruppi come array paralleli:
<?php
$pattern = '/([A-Z][a-z]+) (\d+)/';
$subject = 'Alice 25 Bob 30';
preg_match_all($pattern, $subject, $matches, PREG_PATTERN_ORDER);
print_r($matches[1]); // all names
print_r($matches[2]); // all agesOutput:
Array
(
[0] => Alice
[1] => Bob
)
Array
(
[0] => 25
[1] => 30
)Gruppi di cattura con nome
Assegnare un nome ai gruppi con (?<nome>...) rende il risultato auto-documentante — i nomi diventano chiavi dell'array (insieme agli indici numerici):
<?php
$pattern = '/(?<name>[A-Z][a-z]+) (?<age>\d+)/';
$subject = 'Alice 25 Bob 30';
preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
echo "{$match['name']} is {$match['age']}\n";
}Output:
Alice is 25
Bob is 30Errori comuni
- Controlla il valore restituito, non l'array. Un pattern può corrispondere zero volte e avere comunque successo;
preg_match_all()restituisce0, mentrefalseindica che la regex stessa non era valida. Usa=== falseper rilevare gli errori. Consultapreg_last_error()per il motivo specifico del fallimento. $matchesviene sovrascritto. Ogni chiamata sostituisce il contenuto precedente dell'array di output.- Scegli il flag giusto per il tuo ciclo. Usa
PREG_SET_ORDERquando vuoi una riga per corrispondenza; usa il predefinitoPREG_PATTERN_ORDERquando vuoi una colonna per gruppo. - Esegui l'escape dei caratteri speciali nei pattern dinamici con
preg_quote()quando il pattern proviene dall'input dell'utente.
Conclusione
preg_match_all() restituisce ogni corrispondenza di un pattern in una stringa, rendendola la funzione ideale per estrarre dati ripetuti. La chiave per usarla bene è comprendere l'argomento $flags: PREG_SET_ORDER raggruppa i risultati per occorrenza, mentre il predefinito PREG_PATTERN_ORDER li raggruppa per gruppo di cattura.
Per strumenti correlati, consulta preg_match() per una singola corrispondenza, preg_replace() per la ricerca e la sostituzione, e preg_split() per dividere stringhe con un pattern.