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
?>