PHP - Usando REGEXP ou Expressão Regular para selecionar strings com acentos

REGEXP ou Expressões Regulares já sabemos que são bem complicados, mas esta dica é bem tranquila.

Quantas vezes você já não tentou selecionar aquelas palavras ou frases e quando percebeu... tinha um monte de acentos!

Como consequência ou a palavra não é selecionada ou só um pedaço dela. Vamos começar com o exemplo abaixo utilizando uma frase de Albert Einstein:

<?php 

$html = "<blockquote><p>mais fácil é explodir um <strong>átomo</strong> que um preconceito.</p></blockquote><p><em>Albert Einstein</em></p>";

preg_match_all('/<strong>([a-z]*)/',$html,$cotacao);

var_dump($cotacao);

Teremos como resposta:

array(2) {
  [0]=>
  array(1) {
    [0]=>
    string(8) "<strong>"
  }
  [1]=>
  array(1) {
    [0]=>
    string(0) ""
  }
}

Nossa REGEXP não foi muito feliz. Queríamos pegar toda a palavra depois de <strong> utilizando a expressão regular ([a-z]*) que quer dizer "pegue todos os caracteres de 'a' a 'z' que apareçam nenhuma ou mais vezes" mas o retorno foi nulo. Ele retornou apenas o <strong> que estava na busca declarado de forma explícita.

Bem, isto aconteceu justamente por causa dos acentos. A REGEXP entende literalmente 'a' a 'z'. Variações como 'ç','á','é', etc. não são consideradas. Vamos fazer outro teste tentando pegar um trecho diferente da string:

<?php 

$html = "<blockquote><p>mais fácil é explodir um <strong>átomo</strong> que um preconceito.</p></blockquote><p><em>Albert Einstein</em></p>";

preg_match_all('/<p>([a-z\s]*)/',$html,$cotacao);

var_dump($cotacao);



array(2) {
  [0]=>
  array(2) {
    [0]=>
    string(9) "<p>mais f"
    [1]=>
    string(3) "<p>"
  }
  [1]=>
  array(2) {
    [0]=>
    string(6) "mais f"
    [1]=>
    string(0) ""
  }
}

Aqui alteramos dois elementos. O primeiro foi o ponto inicial da busca, no caso começamos a busca na tag <p>. Além disto acrescentamos a expressão \s para o reconhecimento dos espaços. Bem, tivemos um resultado um pouco diferente pois a REGEXP conseguiu capturar uma parte da string, porém ela truncou exatamente, vejam só, na letra acentuada!

<Ok, já percebemos o problema. Mas o que fazer? Uma solução seria incluir as letras acentuadas separadamente:

<?php 

$html = "<blockquote><p>mais fácil é explodir um <strong>átomo</strong> que um preconceito.</p></blockquote><p><em>Albert Einstein</em></p>";

preg_match_all('/<p>([a-z\sáé]*)/',$html,$cotacao);

var_dump($cotacao);



array(2) {
  [0]=>
  array(2) {
    [0]=>
    string(28) "<p>mais fácil é explodir um "
    [1]=>
    string(3) "<p>"
  }
  [1]=>
  array(2) {
    [0]=>
    string(25) "mais fácil é explodir um "
    [1]=>
    string(0) ""
  }
}

Mas neste ponto você já deve ter percebido que não vai se um bom negócio inserir uma a uma os caracteres acentuados, além do que sempre esquecemos um (ou muitos). Vamos parar de enrolar e mostrar a solução prática:

<?php 

$html = "<blockquote><p>mais fácil é explodir um <strong>átomo</strong> que um preconceito.</p></blockquote><p><em>Albert Einstein</em></p>";

preg_match_all('/<p>([a-zà-ú\s]*)/',$html,$cotacao);

var_dump($cotacao);



array(2) {
  [0]=>
  array(2) {
    [0]=>
    string(28) "<p>mais fácil é explodir um "
    [1]=>
    string(3) "<p>"
  }
  [1]=>
  array(2) {
    [0]=>
    string(25) "mais fácil é explodir um "
    [1]=>
    string(0) ""
  }
}


<?php 

$html = "<blockquote><p>mais fácil é explodir um <strong>átomo</strong> que um preconceito.</p></blockquote><p><em>Albert Einstein</em></p>";

preg_match_all('/<strong>([a-zà-ú]*)/',$html,$cotacao);

var_dump($cotacao);


array(2) {
  [0]=>
  array(1) {
    [0]=>
    string(13) "<strong>átomo"
  }
  [1]=>
  array(1) {
    [0]=>
    string(5) "átomo"
  }
}

O truque está em declarar todos os possíveis caracteres acentuados 'à-ú'. Nossa expressão então fica [a-zà-ú\s] no caso do primeiro exemplo para considerar os espaços e [a-zà-ú] no segundo caso. Assim capturamos todos os caracteres! Neste caso específico pode-se manter o \s em ambas expressões pois será mais geral e não afetará em nada caso não existam espaços na string.

Para considerar inclusive as letras maiúsculas basta fazer [A-zÀ-ú]

Simples e prático não?

Espero que tenha sido útil! Se gostou compartilhe este artigo ou deixe seu comentário!

Comentários

Postagens mais visitadas deste blog

PHP - Utilizando proxy e CURL para acessar servidores ou sites

MySQL - Cálculo de período de tempo entre duas datas com TIMESTAMPDIFF

MySQL - Completando quantidades fixas de caracteres com as funções LPAD() e RPAD()