Fundamentos de Expressões Regulares em PHP
Expressões regulares (regex) são padrões poderosos para buscar, validar e manipular texto. Em PHP, você trabalha com elas através de funções PCRE (Perl Compatible Regular Expressions). As duas funções mais importantes são preg_match() para encontrar padrões e preg_replace() para substituir conteúdo. Dominar essas funções abre portas para validação de dados, parsing de textos complexos e automação de tarefas que seriam impossíveis com simples comparações de strings.
A sintaxe básica segue o padrão /padrão/modificadores. Os delimitadores (/) envolvem o padrão, e após o último delimitador você adiciona modificadores como i (case-insensitive) e g (global). Antes de mergulhar em casos complexos, é essencial entender metacaracteres fundamentais: . (qualquer caractere), * (0 ou mais), + (1 ou mais), ? (0 ou 1), ^ (início), $ (fim), [] (classe de caracteres), | (ou), () (grupo/captura).
// Exemplo básico: validar se uma string contém um padrão
$email = "usuario@dominio.com";
if (preg_match("/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/", $email)) {
echo "Email válido!";
} else {
echo "Email inválido!";
}
preg_match(): Buscando e Capturando Padrões
A função preg_match() retorna 1 se encontra uma correspondência, 0 se não encontra, e false em caso de erro. Seu maior poder está no terceiro parâmetro: um array que captura grupos definidos com parênteses. Cada grupo capturado fica armazenado no array $matches, onde o índice 0 é sempre a correspondência completa, e os índices subsequentes são seus grupos.
// Extrair data no formato DD/MM/YYYY
$texto = "A reunião é em 25/12/2024";
$padrao = "/(\d{2})\/(\d{2})\/(\d{4})/";
if (preg_match($padrao, $texto, $matches)) {
echo "Data completa: " . $matches[0] . "\n"; // 25/12/2024
echo "Dia: " . $matches[1] . "\n"; // 25
echo "Mês: " . $matches[2] . "\n"; // 12
echo "Ano: " . $matches[3] . "\n"; // 2024
}
// Validar e extrair usuário de URL
$url = "https://github.com/joao-silva";
preg_match("/github\.com\/([a-zA-Z0-9_-]+)$/", $url, $matches);
echo "Usuário: " . $matches[1]; // joao-silva
Use classes de caracteres [a-z], [0-9], \d (dígitos), \w (palavras), \s (espaços) para padrões comuns. A função preg_match_all() é similar, mas encontra todas as correspondências, retornando a quantidade de encontros e preenchendo um array estruturado diferente. Para cada encontro adicional, use modificadores quantificadores: {n} (exatamente n), {n,} (n ou mais), {n,m} (entre n e m).
// Encontrar TODAS as hashtags em um texto
$post = "Adorei! #php #regex #programação";
$padrao = "/#([a-zA-Z0-9_]+)/";
preg_match_all($padrao, $post, $matches);
print_r($matches[1]);
// Array ( [0] => php [1] => regex [2] => programação )
preg_replace(): Substituindo e Transformando Conteúdo
preg_replace() é sua ferramenta para transformar strings baseado em padrões. Recebe três parâmetros obrigatórios: padrão, substituição e assunto. Você pode usar grupos capturados na substituição através de $1, $2, etc., referenciando os grupos do padrão. Isso permite transformações avançadas sem processamento adicional em PHP.
// Converter data de DD/MM/YYYY para YYYY-MM-DD
$data_br = "25/12/2024";
$data_iso = preg_replace("/(\d{2})\/(\d{2})\/(\d{4})/", "$3-$2-$1", $data_br);
echo $data_iso; // 2024-12-25
// Remover múltiplos espaços em branco
$texto = "Olá mundo com espaços";
$texto_limpo = preg_replace("/\s+/", " ", $texto);
echo $texto_limpo; // Olá mundo com espaços
// Adicionar prefixo a cada número encontrado
$ids = "123 456 789";
$com_prefixo = preg_replace("/(\d+)/", "ID-$1", $ids);
echo $com_prefixo; // ID-123 ID-456 ID-789
Para trabalhar com arrays, use preg_replace() com arrays como primeiro e segundo parâmetros — cada padrão será substituído pelo correspondente. preg_replace_callback() oferece ainda mais controle, permitindo uma função para processar cada correspondência dinamicamente. Isso é essencial quando a substituição não é simples ou depende de lógica adicional.
// Substituir múltiplos padrões com arrays
$padroes = ["/\[B\](.*?)\[\/B\]/i", "/\[I\](.*?)\[\/I\]/i"];
$substitui = ["<b>$1</b>", "<i>$1</i>"];
$html = preg_replace($padroes, $substitui, "[B]Negrito[/B] e [I]Itálico[/I]");
echo $html; // <b>Negrito</b> e <i>Itálico</i>
// Converter minúsculas para MAIÚSCULAS apenas em números específicos
$numero = preg_replace_callback("/(\d+)/", function($m) {
return "NUM-" . strtoupper(dechex($m[1]));
}, "Valores: 255 100 50");
echo $numero; // Valores: NUM-FF NUM-64 NUM-32
Casos Práticos Essenciais
Na prática profissional, você usa regex para validar CPF/CNPJ, formatar telefones, sanitizar entrada de usuários e extrair dados de HTML ou APIs. Sempre lembre: regex é poderosa mas pode ficar ilegível rapidamente. Use x modificador para comentar padrões complexos, dividindo em múltiplas linhas. Teste seus padrões em ferramentas online antes de integrar ao código.
// Validar CPF (formato XXX.XXX.XXX-XX)
$cpf = "123.456.789-10";
if (preg_match("/^\d{3}\.\d{3}\.\d{3}\-\d{2}$/", $cpf)) {
echo "Formato válido";
}
// Extrair todos os links de uma página HTML
$html = '<a href="http://exemplo.com">Link 1</a> <a href="http://outro.com">Link 2</a>';
preg_match_all('/<a\s+href=["\'](.*?)["\']/i', $html, $links);
print_r($links[1]);
// Array ( [0] => http://exemplo.com [1] => http://outro.com )
// Sanitizar nomes de arquivo (apenas alphanuméricas, hífens e underscores)
$filename = "Meu Arquivo@2024!.pdf";
$safe = preg_replace("/[^a-zA-Z0-9._-]/", "", $filename);
echo $safe; // MeuArquivo2024.pdf
Conclusão
Dominar preg_match() e preg_replace() significa ganhar eficiência brutal em validação e transformação de dados. O primeiro captura e extrai informações estruturadas; o segundo transforma conteúdo em escala. Lembre-se: sempre teste seus padrões com casos extremos (strings vazias, caracteres especiais, Unicode), use preg_last_error() para debugar e documente padrões complexos com comentários. A prática constante transformará regex de um mistério em uma ferramenta natural no seu arsenal de programador.