preg_match_all()
A função preg_match_all() em PHP retorna todas as ocorrências de um padrão em uma string. Aprenda a sintaxe, flags e exemplos práticos.
Introdução
Em PHP, expressões regulares são essenciais para pesquisar e manipular strings. Enquanto preg_match() para na primeira correspondência, preg_match_all() continua verificando e retorna todas as ocorrências de um padrão em uma string. Use-a sempre que precisar extrair todos os números de telefone, todas as tags, todas as palavras ou qualquer estrutura repetida de um texto.
Este artigo explica a sintaxe, o importante argumento $flags que controla como os resultados são organizados, e vários exemplos práticos.
Sintaxe
preg_match_all(
string $pattern,
string $subject,
array &$matches = null,
int $flags = PREG_PATTERN_ORDER,
int $offset = 0
): int|false$pattern— a expressão regular, delimitada por/.../(ou qualquer delimitador correspondente).$subject— a string a ser pesquisada.$matches— um array de saída (passado por referência) preenchido com todas as correspondências encontradas.$flags— opcional. Controla como$matchesé estruturado (veja abaixo).$offset— opcional. Deslocamento em bytes em$subjecta partir do qual iniciar a pesquisa.
Retorna o número de correspondências completas do padrão (que pode ser 0), ou false se o padrão for inválido.
Uma correspondência simples
O uso mais básico é coletar cada substring que corresponde a um padrão. Aqui extraímos todos os números de uma 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]);Saída:
Found 3 numbers
Array
(
[0] => 12
[1] => 3
[2] => 7
)Quando o padrão não tem grupos de captura, $matches[0] contém a lista de correspondências completas.
Escolhendo uma flag: PREG_PATTERN_ORDER vs PREG_SET_ORDER
O argumento $flags decide como as correspondências e os grupos de captura são organizados. As duas flags principais são mutuamente exclusivas:
PREG_PATTERN_ORDER(o padrão) —$matches[0]contém todas as correspondências completas,$matches[1]contém todas as capturas do grupo 1,$matches[2]contém todas as capturas do grupo 2, e assim por diante. Pense "coluna por coluna."PREG_SET_ORDER—$matches[0]é a primeira correspondência completa (correspondência completa + seus grupos),$matches[1]é a segunda, e assim por diante. Pense "linha por linha."
Você também pode adicionar PREG_OFFSET_CAPTURE para registrar o deslocamento em bytes de cada correspondência junto com seu texto.
PREG_SET_ORDER (agrupar resultados por ocorrência)
Esse layout é o mais fácil de percorrer quando cada correspondência tem vários grupos de captura:
Saída:
Name: Alice, Age: 25
Name: Bob, Age: 30Com PREG_SET_ORDER, cada $match é uma ocorrência: $match[0] é a correspondência completa, $match[1] é o primeiro grupo (nome), $match[2] é o segundo grupo (idade).
PREG_PATTERN_ORDER (agrupar resultados por padrão)
O mesmo padrão com a flag padrão retorna os grupos como arrays paralelos:
<?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 agesSaída:
Array
(
[0] => Alice
[1] => Bob
)
Array
(
[0] => 25
[1] => 30
)Grupos de captura nomeados
Nomear grupos com (?<name>...) torna o resultado autodocumentado — os nomes se tornam chaves do array (juntamente com os índices numéricos):
<?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";
}Saída:
Alice is 25
Bob is 30Armadilhas comuns
- Verifique o valor de retorno, não o array. Um padrão pode corresponder zero vezes e ainda assim ter sucesso;
preg_match_all()retorna0, enquantofalsesignifica que a própria regex era inválida. Use=== falsepara detectar erros. Consultepreg_last_error()para o motivo específico da falha. $matchesé sobrescrito. Cada chamada substitui o conteúdo anterior do array de saída.- Escolha a flag certa para seu loop. Use
PREG_SET_ORDERquando quiser uma linha por correspondência; use o padrãoPREG_PATTERN_ORDERquando quiser uma coluna por grupo. - Escape caracteres especiais em padrões dinâmicos com
preg_quote()quando o padrão vem de entrada do usuário.
Conclusão
preg_match_all() retorna todas as correspondências de um padrão em uma string, tornando-a a função ideal para extrair dados repetidos. A chave para usá-la bem é entender o argumento $flags: PREG_SET_ORDER agrupa os resultados por ocorrência, enquanto o padrão PREG_PATTERN_ORDER os agrupa por grupo de captura.
Para ferramentas relacionadas, consulte preg_match() para uma única correspondência, preg_replace() para localizar e substituir, e preg_split() para dividir strings por um padrão.