Menu

PHP preg_match(): expressões regulares com exemplos

preg_match($pattern, $subject, $matches) testa uma string contra uma expressão regular e retorna 1 quando bate, 0 quando não bate. Veja grupos de captura, grupos nomeados, preg_match_all, âncoras, padrões de validação e o modificador u para UTF-8 e texto japonês.

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

preg_match($pattern, $subject, $matches) verifica se uma string bate com uma expressão regular. Ele retorna 1 quando bate e 0 caso contrário, e preenche $matches com o que encontrou: preg_match('/\d+/', 'Order 4521 shipped', $m) retorna 1 e define $m[0] como "4521".

O padrão é uma string com delimitadores em volta, normalmente /.../, seguida de modificadores como i. Escreva padrões entre aspas simples: dentro de aspas duplas o PHP primeiro expande $name e escapes como \x41 ou \101, então o motor de regex pode receber um padrão diferente do que você digitou.

Grupos de captura

Parênteses num padrão capturam a parte da string com que batem. $m[0] é a correspondência inteira, $m[1] o primeiro grupo, $m[2] o segundo, contados pelo parêntese de abertura a partir da esquerda.

Grupos nomeados

(?<name>...) dá um nome a um grupo. O valor é guardado sob o nome e sob o número, então o código que lê o resultado não quebra quando alguém adiciona um grupo antes no padrão.

Encontrar todas as correspondências com preg_match_all

O preg_match_all() continua procurando depois da primeira correspondência e retorna o número de correspondências. Por padrão, $m[0] guarda todas as correspondências completas e $m[1] todos os valores do primeiro grupo. Com PREG_SET_ORDER você recebe um array por correspondência, o que é mais fácil de percorrer.

Validar entradas: âncoras, telefones, códigos postais

Para validação, o padrão precisa bater com a string inteira, então comece com ^ e termine com $. Uma armadilha: $ também bate antes de uma quebra de linha final, então '/^\d+$/' aceita "123\n". Adicione o modificador D, ou use \z, que só bate no fim exato.

Para endereços de e-mail, uma regex ou rejeita endereços válidos ou aceita inválidos. Use filter_var($email, FILTER_VALIDATE_EMAIL) no lugar (veja filter_var()).

O modificador u para UTF-8 e texto japonês

Sem o modificador u, um padrão trabalha com bytes. Um caractere japonês tem três bytes em UTF-8, então . bate com um terço de um caractere e os tamanhos saem errados. Com u, o padrão trabalha com caracteres e você pode usar classes de propriedades Unicode.

O u também valida o texto: se a string não for UTF-8 válido, o preg_match() retorna false em vez de procurar.

Escapar entradas do usuário com preg_quote

Caracteres como ., +, ?, ( e / têm significado especial num padrão. Se parte do padrão vem de uma variável, como um termo de busca, passe-a pelo preg_quote() com o delimitador como segundo argumento, senão 1+1 vai bater com 11 e uma / sem escape quebra o padrão.

Um padrão inválido não lança exceção. O PHP imprime um aviso e o preg_match() retorna false:

Warning: preg_match(): No ending delimiter '/' found in /path/to/index.php on line 3

Então verifique === false (ou preg_last_error_msg()) quando o padrão é montado em tempo de execução. Para uma simples verificação de substring sem padrão nenhum, o str_contains() é mais rápido e mais claro. Para alterar o texto encontrado, use o preg_replace().

Perguntas frequentes

O que o preg_match retorna no PHP?

1 se o padrão bate, 0 se não bate, e false se o próprio padrão é inválido. Como 0 e false são falsos, compare com === 1 quando precisar distinguir um padrão quebrado de nenhuma correspondência.

Como pego o texto encontrado pelo preg_match?

Passe um terceiro argumento: preg_match('/(\d+)/', 'Order 4521', $m). Então $m[0] é a correspondência inteira e $m[1] o primeiro grupo de captura, os dois "4521" aqui. Com um grupo nomeado (?<id>\d+), o valor também fica em $m['id'].

Qual a diferença entre preg_match e preg_match_all?

O preg_match() para na primeira correspondência. O preg_match_all() encontra todas, retorna quantas encontrou e preenche $matches com todas elas: preg_match_all('/\d+/', 'a1 b22 c333', $m) retorna 3 e $m[0] é ["1", "22", "333"].

Como uso preg_match com texto acentuado, japonês ou outro UTF-8?

Adicione o modificador u: preg_match('/^.{3}$/u', '日本語') retorna 1. Sem u, o PHP trata a string como bytes, então . bate com um byte de um caractere de 3 bytes. Com u você também pode usar classes Unicode como \p{Han}, \p{Hiragana} e \p{Katakana}.

Como verifico se uma string contém só números no PHP?

preg_match('/^\d+$/D', $s) ou, sem regex, ctype_digit($s). O modificador D (ou \z no lugar de $) importa: um $ simples também aceita uma quebra de linha final, então "123\n" passaria.

Ilustração das linguagens de programação do Coddy

Aprenda a programar com o Coddy

COMEÇAR