Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Bom, minha dúvida é mais didática do que aplicada, mas vamos ao assunto. Não entrarei em detalhes sobre como criar uma expressão regular, e sim como usar backreference.
Para criação de máscaras, pode-se utilizar preg_replace e backreference (referência passada, referência anterior ou retrovisor, vai de cada autor) para um padrão. Vamos ao exemplo de um telefone +55 (54) 9999-9999.
Número sem a máscara:
555499999999
Expressão regular para a máscara com backreference
preg_replace( '/^([\d]{2})([\d]{2})([\d]{4})([\d]{4})$/', '+${1} (${2}) ${3}-${4}', '555499999999');
A expressão, nada mais faz que "casar" os conjuntos de caracteres, armazena-os, e após é utilizado no "retrovisor" ${1} sendo o primeiro grupo e assim sucessivamente.
Agora a minha aplicação prática. Eu recebo de uma lista em excel totalmente desformatada que pode concluir de 1 a n números de telefone no mesmo campo.
Imaginemos que os campo seja assim:
+55 (54) 9999-9999 / +55 (54) 9999-9999 / +55 (54) 9999-9999
+55 (54) 9999-9999 / +55 (54) 9999-9999
+55 (54) 9999-9999 / +55 (54) 9999-9999 / +55 (54) 9999-9999 / +55 (54) 9999-9999
+55 (54) 9999-9999
Beleza, casar isso (somente números como é próprio de trablhar) é extremamente fácil:
preg_match( '/^(([\d]{2})([\d]{2})([\d]{4})([\d]{4})){1,}$/', '555499999999');
O código acima irá casar o conjunto de caracteres mesmo se repetirem infinitamente.
O meu problema/dúvida é, como eu posso referenciar essa repetição no retrovisor? Especificamente no PHP.
Algumas linguagens de programação implementam laços a nível de programação e não da expressão regular
Não vou morrer se não houver como, mas gostaria de saber se existe algo a nível de "expressão regular".
A solução mais viável a seguinte
preg_match( '/^([\d]{12}){1,}$/', $telefones, $dados );
$telefones = array();
foreach( $dados AS $telefone ) {
$telefones[] = preg_replace( '/^([\d]{2})([\d]{2})([\d]{4})([\d]{4})$/', '+${1} (${2}) ${3}-${4}', $telefone );
}
echo implode( ' / ', $telefones );
Acho interessante exmplorar o máximo as funções pouco utilizadas. Poucos programadores utilizam o recurso de backreference.
Tive de atualizar, pois não é um problema, é uma dúvida.
Você fala no caso de haver vários telefones concatenados e você separá-los e aplicar a máscara?
Sim e não.
A idéia não seria separa-los e depois aplicar a máscara. E sim somente aplicar a mascar, sem precisar separar os valores. Utilizando somente o preg_replace.
Pois uma solução já está no final do código.
Como eu falei, isso é somente a nível didático meu (mania de querer saber tudo que pode-se fazer). Mas pelo que eu vi, não é possível.
Cara, não consegui entender o que você quer :upset:
Seria isso (basta remover o início(^) e o fim($)):
<?php
$telefones = '555499999999555499999999555499999999555499999999555499999999555499999999';
var_dump( rtrim( preg_replace( '/([\d]{2})([\d]{2})([\d]{4})([\d]{4})/', '+${1} (${2}) ${3}-${4} / ', $telefones ), ' /' ) );
Saída:
+55 (54) 9999-9999 / +55 (54) 9999-9999 / +55 (54) 9999-9999 / +55 (54) 9999-9999 / +55 (54) 9999-9999 / +55 (54) 9999-9999
Dá pra aplicar a máscara a vários telefones sem separar os valores, basta tirar os delimitadores ^ e $.
@Carlos Coelho
É uma solução, mas é a nível do PHP. O que eu queria mesmo era saber se, existe como criar um laço dentro do replacemente utilizando os retrovisores.
>
Dá pra aplicar a máscara a vários telefones sem separar os valores, basta tirar os delimitadores ^ e $.
E como fica a barra? Não fica.
Estou sendo chato justamente por achar "muito" fácil fazer de outra forma, e gostaria de saber se existiria dentro do preg_replace.
Cara, não consegui entender o que você quer :upset:
Por exemplo, para "casar" uma data pode ser da seguinte forma.:
^[\d]{2}\/[\d]{2}\/[\d]{4}$
como pode-se simplificar para:
^([\d]{2}\/){2}[\d]{4}$
Assim, evito de escrever um grupo que se repete. Era essa simplificação que eu gostaria de encontrar no replacemente e utilizar os retrovisores.
O que eu queria é, do mesmo modo que pode-se utilizar uma repetição para evitar reescrita dentro do pattern. Gostaria de saber se haveria como utilizar a mesma repetição para os retrovisores.
A única coisa fora do preg_replace foi remover a barra com rtrim, se não te incomoda deixar uma barra solta no final... :rolleyes:
>
A única coisa fora do preg_replace foi remover a barra com rtrim, se não te incomoda deixar uma barra solta no final... :rolleyes:
Claro que não me incomoda. Como eu falei mais acima, não é um problema é só uma dúvida de se é possível ou não.
É que eu sou teimoso a ponto de procurar tudo que uma função pode oferecer.
Como assim?
Você fala no caso de haver vários telefones concatenados e você separá-los e aplicar a máscara?