programação,

PHP - Expressões regulares

Diogo Matheus Diogo Matheus Seguir 19/03/2012 · 8 minutos de leitura
PHP - Expressões regulares
Compartilhar

Expressão regular é uma forma de se especificar um padrão de texto e pode ser composta por símbolos, caracteres literais e caracteres com funções especiais, que agrupados formam uma expressão. Essa expressão é interpretada como uma regra, onde uma entrada de dados qualquer é bem sucedida somente se obedecer a essa regra.

Didaticamente podemos comparar expressões regulares com o brinquedo LEGO, onde temos várias opções de peças disponíveis e de diferentes tipos, que juntas possibilitam a construção de estruturas complexas.

Por exemplo, observe o conjunto de nomes abaixo:

{Diogo, Renato, Gomes, Thiago, Leonardo}

Se criarmos uma expressão regular para buscar pelo padrão “go”, sem diferenciar maiúsculas de minúsculas, ou seja, case-insensitive, iremos obter os seguintes nomes:

{Diogo, Gomes, Thiago}

Neste caso, todos os nomes que possuem “go” são válidos, afinal obedecem a regra, mas poderíamos ir mais além, definindo que queremos apenas os nomes que terminem com “go” ou iniciem, mas deixaremos isso mais para frente, antes conheceremos as peças disponíveis.

Geralmente expressões regulares são utilizadas no desenvolvimento de aplicações para validar entradas de dados, por exemplo, verificar se o CEP que um determinado usuário informou obedece aos padrões conhecidos de um CEP, se um email tem uma estrutura válida, etc.

Conhecendo as peças disponíveis, os metacaracteres

Os metacaracteres estão divididos em grupos distintos, de acordo com características comuns.

Representantes

Os metacaracteres representantes têm como função representar um ou mais caracteres, são como apelidos, todos metacaracteres deste tipo casam a posição de um único caractere.

Metacaractere Nome Descrição
. Ponto Um caractere qualquer.
[…] Lista Lista de caracteres permitidos.
[^…] Lista negada Lista de caracteres proibidos.
e.tendido
Casa com: estendido, extendido, eztendido, ...
 
e[sx]tendido
Casa com: estendido, extendido
 
e[^x]tendido
Casa com: estendido, ...
Não casa com: extendido

Intervalo de caracteres

Os intervalos entre caracteres são representados por um traço entre dois caracteres, [0-9], [a-z], [A-Z].

[0-9]
Casa com: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

Classes de caracteres POSIX

São grupos definidos por tipo, POSIX é um padrão internacional que define determinado tipo de regra, sintaxe e etc.

POSIX Nome Descrição
[:upper:] [A-Z] Letras maiúsculas.
[:lower:] [a-z] Letras minúsculas.
[:alpha:] [A-Za-z] Letras maiúsculas e minúsculas.
[:alnum:] [A-Za-z0-9] Letras e números.
[:digit:] [0-9] Números.
[:xdigit:] [0-9A-Fa-f] Números hexadecimais.
[:punct:] [.,!?:…] Sinais de pontuação.
[:blank:] [ \t] Espaço e TAB.
[:space:] [ \t\n\r\f\v] Caracteres brancos.
[:cntrl:] Caracteres de controle.
[:graph:] [^ \t\n\r\f\v] Caracteres imprimíveis.
[:print:] [^\t\n\r\f\v] Imprimíveis e o espaço.

Todas as opções a seguir são equivalentes, representando letras minúsculas, maiúsculas e números.

[A-Za-z0-9]
[[:upper:][:lower:][:digit:]]
[[:alpha:][:digit:]]
[[:alnum:]]

Classes de caracteres POSIX levam em conta a localidade do sistema, isso é importante para trabalhar com acentuação, ou seja, classes que trabalham com letras, englobam seus equivalentes com acentos.

Quantificadores

Os metacaracteres quantificadores são utilizados para indicar o número de repetições permitidas para a entidade anterior, essa entidade pode ser um caractere ou metacaractere.

Metacaractere Nome Descrição
? Opcional Zero ou um.
* Asterisco Zero, um ou mais.
+ Mais Um ou mais.
{n,m} Chaves De n até m.
Th?iago
Casa com: Thiago, Tiago
 
Diogo*
Casa com: Diog, Diogo, Diogoo, Diogooo, ...
 
Diogo+
Casa com: Diogo, Diogoo, Diogooo, ...
 
Diogo{1,2}
Casa com: Diogo, Diogoo
 
Diogo{2}
Casa com: Diogoo

Âncoras

Os metacaracteres âncoras marcam uma posição específica na linha.

Metacaractere Nome Descrição
^ Circunflexo Início da linha.
$ Cifrão Fim da linha.
\b Borda Início ou fim de palavra.
\bD[a-z]+
Casa com: Diogo, Dado, Dia, ...
 
^D[a-z]+
Casa com: Diogo, Dado, Dia, ...
 
[A-Za-z]+o$
Casa com: Thiago, Quadrado, Redondo, ...

Nos exemplos acima os metacaracteres \b e ^ possuem o mesmo efeito, isso porque estamos testando com palavras e nomes, em uma frase o \b verificaria palavra por palavra, já o ^ iria verificar apenas o início da frase.

Outros

Além dos metacaracteres que vimos até agora, existem outros que possuem funções específicas e não relacionadas entre si, confira alguns abaixo:

Metacaractere Nome Descrição
\c Escape Torna literal o caractere c.
| Ou Ou um ou outro.
(…) Grupo Delimita um grupo.
\1…\9 Retrovisor Texto casado nos grupos 1…9.
R\$
Casa com: R$
 
Diogo|Thiago
Casa com: Diogo, Thiago
 
boa-(tarde|noite)
Casa com: boa-tarde, boa-noite
 
(quero)-\1
Casa com: quero-quero

Metacaracteres tipo barra-letra

São átomos representados por uma barra invertida \ seguida de uma letra qualquer, como \s. Dependendo da letra muda-se o significado do metacaractere.

Metacaractere POSIX Descrição
\d [[:digit:]] Digito.
\D [^[:digit:]] Não-digito.
\w [[:alnum:]_] Palavra.
\W [^[:alnum:]_] Não-palavra.
\s [[:space:]] Branco.
\S [^[:space:]] Não-branco.
\d
Casa com: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

Você pode usar o website regexpal para testar suas expressões regulares.

Expressões regulares no PHP

Atualmente o PHP oferece duas maneiras distintas de trabalhar com expressões regulares, POSIX e PCRE, cada alternativa conta com um conjunto de funções, confira.

POSIX Descrição
ereg_replace Busca e substitui o que casar com a expressão.
ereg Verifica se uma string casa com a expressão.
eregi_replace Igual a ereg_replace, porém é case-insensitive.
eregi Igual a ereg, porém é case-insensitive.
split Divide uma string utilizando uma expressão.
spliti Igual a split, porém é case-insensitive.
sql_regcase Cria uma expressão regular para uma determinada entrada.
PCRE Descrição
preg_filter Busca e substitui, retornando as opções do array que casarem com a expressão.
preg_grep Retorna as opções de um array que casarem com a expressão.
preg_last_error Retorna o código de erro da última expressão executada.
preg_match_all Retorna as ocorrências de uma string que casarem com a expressão.
preg_match Verifica se uma string casa com a expressão.
preg_quote Adiciona escape em caracteres da expressão.
preg_replace_callback Busca e executa um callback nas opções que casarem com a expressão.
preg_replace Busca e substitui, retornando todas as opções.
preg_split Divide uma string utilizando uma expressão.

Diferença entre PCRE e POSIX

As funções preg (PCRE) utilizam a biblioteca PCRE, que a partir da versão 5.3 do PHP não pode ser desabilitada, sendo assim, estará sempre presente, essas funções são compatíveis com estilo PERL e possuem características não disponíveis nas funções ereg(POSIX).

A partir da versão 5.3 do PHP as funções ereg (POSIX) foram marcadas como deprecated, ou seja, tornaram-se obsoletas e seu uso é desencorajado, além disso toda vez que são utilizadas é lançado um notice do tipo E_DEPRECATED.

Trabalhando com expressões regulares no PHP

Agora que conhecemos os principais metacaracteres para criar uma expressão regular e as funções PCRE, vamos praticar.

<?php
$cep = '22710-045';
$names = array('Diogo', 'Renato', 'Gomes', 'Thiago', 'Leonardo');
$text = 'Lorem ipsum dolor sit amet, consectetuer adipiscing.';
 
// Validação de CEP
$er = '/^(\d){5}-(\d){3}$/';
if(preg_match($er, $cep)) {
    echo "O cep casou com a expressão.";
}
// Resultado: O cep casou com a expressão.
 
// Busca e substitui nomes que tenham "go", case-insensitive
$er = '/go/i';
$pregReplace = preg_replace($er, 'GO', $names);
print_r($pregReplace);
// Resultado: DioGO, Renato, GOmes, ThiaGO, Leonardo
 
// Busca e substitui nomes que terminam com "go"
$er = '/go$/';
$pregFilter = preg_filter($er, 'GO', $names);
print_r($pregFilter);
// Resultado: DioGO, ThiaGO
 
// Resgatar nomes que começam com "go", case-insensitive
$er = '/^go/i';
$pregGrep = preg_grep($er, $names);
print_r($pregGrep);
// Resultado: Gomes
 
// Divide o texto por pontos e espaços, que podem ser seguidos por espaços
$er = '/[[:punct:]\s]\s*/';
$pregSplit = preg_split($er, $text);
print_r($pregSplit);
// Resultado: Array de palavras
 
// callback, retorna em letras maiúsculas
$callback = function($matches) {
    return strtoupper($matches[0]);
};
 
// Busca e substitui de acordo com o callback
$er = '/(.*)go$/';
$pregCallback = preg_replace_callback($er, $callback, $names);
print_r($pregCallback);
// Resultado: DIOGO, Renato, Gomes, THIAGO, Leonardo
?>