Expressões regulares
Nesta aula, você aprenderá a usar expressões regulares em PHP com as funções preg_match e preg_replace, compreenderá a sintaxe PCRE, como trabalhar com grupos de captura e aplicará esses conhecimentos em casos comuns do dia a dia.
Expressões regulares (regex) são uma ferramenta poderosa para buscar, validar e manipular texto de forma padronizada. Em PHP, elas são amplamente utilizadas para tarefas como validação de formulários, extração de informações de strings e substituição de padrões. Esta aula vai guiá-lo desde o básico até técnicas mais avançadas, com exemplos práticos e explicações detalhadas.
Dominar regex é essencial para qualquer desenvolvedor PHP, pois permite escrever código mais limpo e eficiente quando se trata de processamento de texto. Vamos explorar as funções principais, a sintaxe PCRE (Perl Compatible Regular Expressions) usada pelo PHP, e ver como aplicar esses conceitos em situações reais.
preg_match, preg_replace
As duas funções mais comuns para trabalhar com regex em PHP são preg_match e preg_replace. preg_match verifica se um padrão existe em uma string e retorna 1 se encontrado, 0 se não, ou false em caso de erro. Ela também pode preencher uma variável com os resultados da correspondência, incluindo grupos de captura.
Exemplo básico de preg_match:
$texto = "O número é 1234";
if (preg_match('/\d+/', $texto, $matches)) {
echo "Encontrado: " . $matches[0];
} else {
echo "Nenhum número encontrado.";
}
// Saída: Encontrado: 1234Já preg_replace substitui todas as ocorrências do padrão por uma string de substituição. É útil para limpar dados, formatar texto ou modificar conteúdo dinamicamente.
Exemplo de preg_replace:
$texto = "Telefone: (11) 98765-4321";
$somenteNumeros = preg_replace('/\D/', '', $texto);
echo $somenteNumeros; // Saída: 11987654321Note que o padrão \D corresponde a qualquer caractere que não seja dígito. A substituição por string vazia remove tudo exceto números.
Sintaxe PCRE
PCRE (Perl Compatible Regular Expressions) é a biblioteca usada pelo PHP para expressões regulares. A sintaxe é semelhante à do Perl, e é importante conhecer os metacaracteres básicos: . (qualquer caractere), ^ (início da string), $ (fim da string), [] (classe de caracteres), () (grupo), * (zero ou mais), + (um ou mais), ? (zero ou um), {n,m} (de n a m ocorrências), e o escape \ para caracteres especiais.
Um aspecto importante é que as expressões regulares devem ser delimitadas por um caractere delimitador, geralmente /, mas pode ser qualquer caractere não alfanumérico. Após o delimitador final, podem ser usados modificadores como i (case-insensitive), m (multiline), s (dotall), entre outros.
Exemplo de uso de modificadores:
$texto = "PHP é ótimo";
// Verifica se contém "php" (case-insensitive)
if (preg_match('/php/i', $texto)) {
echo "Encontrou 'php' independente de caixa.";
}Entender a sintaxe PCRE é crucial para criar padrões precisos. Por exemplo, \d representa dígitos, \w representa caracteres de palavra (letras, dígitos e sublinhado), e \s representa espaços em branco. Esses atalhos são muito úteis.
Grupos
Grupos são criados com parênteses () e servem para capturar partes da correspondência ou para aplicar quantificadores a um conjunto de caracteres. Cada grupo capturado é armazenado em $matches na ordem de abertura.
Exemplo de captura de grupos:
$data = "Data: 2025-03-14";
if (preg_match('/(\d{4})-(\d{2})-(\d{2})/', $data, $matches)) {
echo "Ano: " . $matches[1] . "\n";
echo "Mês: " . $matches[2] . "\n";
echo "Dia: " . $matches[3] . "\n";
}
// Saída:
// Ano: 2025
// Mês: 03
// Dia: 14Além de capturar, grupos podem ser usados para agrupar alternativas ou aplicar quantificadores. Por exemplo, (ab)+ corresponde a uma ou mais repetições de "ab".
É possível também usar grupos não capturantes com (?:...), que agrupam sem armazenar o resultado. Isso é útil para evitar sobrecarga de memória quando não precisamos do valor capturado.
$texto = "abc abc abc";
// Conta quantas vezes "abc" aparece (não captura)
preg_match_all('/(?:abc)/', $texto, $matches);
echo count($matches[0]); // 3Casos comuns
As expressões regulares são frequentemente usadas para validação de dados. Vamos ver alguns casos comuns:
Validação de e-mail
$email = "usuario@exemplo.com";
if (preg_match('/^[\w.+-]+@[\w-]+\.[\w.-]+$/', $email)) {
echo "E-mail válido.";
} else {
echo "E-mail inválido.";
}Extração de URLs
$texto = "Visite https://www.exemplo.com e http://outro.org";
preg_match_all('/https?:\/\/[\w.-]+/', $texto, $urls);
print_r($urls[0]);
// Saída: Array ( [0] => https://www.exemplo.com [1] => http://outro.org )Substituição de palavras
$texto = "O gato é preto. A gata é branca.";
$novoTexto = preg_replace('/gato|gata/', 'felino', $texto);
echo $novoTexto;
// Saída: O felino é preto. A felino é branca.Boas práticas e observações finais
Ao trabalhar com regex em PHP, é importante lembrar de escapar corretamente as barras dentro do padrão se você usar o delimitador /. Uma alternativa é usar outros delimitadores, como ~, para evitar escapes desnecessários. Além disso, teste sempre suas expressões com casos extremos para garantir que elas não sejam muito permissivas ou restritivas.
Outra dica é usar o modificador u para trabalhar com Unicode, garantindo que caracteres acentuados sejam tratados corretamente. Por fim, evite regex complexas quando houver funções específicas do PHP para a tarefa, como filter_var para validação de e-mail.
Referências
- Documentação oficial PCRE do PHP
- preg_match no PHP.net
- preg_replace no PHP.net
- Referência de sintaxe de regex no PHP
- Regular-Expressions.info - Guia completo
- Regex101 - Testador online de regex
Exercícios
- Escreva uma função PHP que use
preg_matchpara validar se uma string é um CPF no formato 000.000.000-00. - Utilize
preg_replacepara remover todas as tags HTML de uma string, exceto as tags<b>e<i>. - Crie uma expressão regular que capture o nome de usuário e o domínio de um e-mail em grupos separados.
- Escreva um código que use
preg_match_allpara encontrar todas as palavras que começam com "php" (case-insensitive) em um texto. - Use
preg_replace_callbackpara transformar todas as ocorrências de datas no formato dd/mm/aaaa para aaaa-mm-dd.
function validarCPF($cpf) {
return preg_match('/^\d{3}\.\d{3}\.\d{3}-\d{2}$/', $cpf) === 1;
}
// Teste:
var_dump(validarCPF('123.456.789-00')); // true
var_dump(validarCPF('12345678900')); // false$html = '<p>Olá <b>mundo</b>!</p>';
$semTags = preg_replace('/<\/?(?!b|i)\w+[^>]*>/i', '', $html);
echo $semTags; // Olá <b>mundo</b>!$email = 'user@example.com';
if (preg_match('/^([\w.+-]+)@([\w-]+\.[\w.-]+)$/', $email, $matches)) {
echo "Usuário: " . $matches[1] . "\n";
echo "Domínio: " . $matches[2] . "\n";
}$texto = "PHP é uma linguagem, e phpMyAdmin é uma ferramenta. PHPDoc é usado para documentação.";
preg_match_all('/\bphp\w*/i', $texto, $palavras);
print_r($palavras[0]);
// Saída: Array ( [0] => PHP [1] => phpMyAdmin [2] => PHPDoc )$texto = "Hoje é 14/03/2025 e amanhã será 15/03/2025.";
$novoTexto = preg_replace_callback('/(\d{2})\/(\d{2})\/(\d{4})/', function($m) {
return "$m[3]-$m[2]-$m[1]";
}, $texto);
echo $novoTexto;
// Saída: Hoje é 2025-03-14 e amanhã será 2025-03-15.