MySQL – Pesquisa em Registros com Acento com PHP

[ads2]
Muita gente já teve problemas ao fazer consultas no MySQL quando o registro tem algum caractere com acento. Eu já tive, mas consegui resolver com uma alternativa.

Função REGEXP()

Você conhece esta função? REGEXP é uma expressão regular que pode ser usada na otimização de buscas. Ela pode substituir a cláusula LIKE ou a IN, tendo mais opções e sendo assim mais eficiente.
Uma consulta que você faria com vários LIKEs, você pode fazer com apenas um REGEXP. E em relação ao IN é como se fosse um IN potencializado, pois é possivel colocar opções dentro das opções, por exemplo:
Exemplo com IN:

SELECT * FROM USUARIO WHERE NOME IN("Jose","Antonio");

Exemplo com REGEXP:

SELECT * FROM USUARIO WHERE NOME REGEXP("Jose|Antonio");

Mas pera ia, onde está a diferença? É, realmente do jeito que foi mostrado não faz nenhuma diferença, mas vamos supor que em sua tabela você tenha usuários com o nome José, com e sem acento, e então como fará para filtrar isso? É ai que entra uma das vantagens do REGEXP. Veja:

SELECT * FROM USUARIO WHERE NOME REGEXP "Jos(é|e)|Ant(ô|o)nio";

Além disso podem ser usadas também apenas partes dos nomes, mas acho que isso já é suficiente para o objetivo do nosso post.

Agora, imagino que você esteja desenvolvendo um formulário de pesquisa em seu site ou sistema WEB, certo? E provavelmente está usando PHP para fazer a consulta no banco de dados, e então precisa tratar as strings da pesquisa, para que elas fiquem de acordo com o que a função REGEXP trabalha.

Para isso eu desenvolvi uma função PHP que substitui todas as vogais por cláusulas REGEXP e também o “Ç”. Veja:

 'a', 
    	'à' => 'a', 
    	'ã' => 'a', 
    	'â' => 'a',
    	'é' => 'e', 
    	'ê' => 'e', 
    	'í' => 'i', 
    	'ó' => 'o', 
    	'ô' => 'o', 
    	'õ' => 'o', 
    	'ú' => 'u', 
    	'ü' => 'u', 
    	'ç' => 'c', 
    	'Á' => 'A', 
    	'À' => 'A', 
    	'Ã' => 'A', 
    	'Â' => 'A', 
    	'É' => 'E', 
    	'Ê' => 'E', 
    	'Í' => 'I', 
    	'Ó' => 'O', 
    	'Ô' => 'O', 
    	'Õ' => 'O', 
    	'Ú' => 'U', 
    	'Ü' => 'U', 
    	'Ç' => 'C'
	);

    //Array para REGEXP
    $regpx = array(
    	'a' => '(a|á|á|à|à|â|â|ã|ã)', 
    	'A' => '(a|á|á|à|à|â|â|ã|ã)', 
    	'e' => '(e|é|é|è|è|ê|ê)', 
    	'E' => '(e|é|é|è|è|ê|ê)', 
    	'i' => '(i|í|í|ì|ì|î|î)', 
    	'I' => '(i|í|í|ì|ì|î|î)', 
    	'o' => '(o|ó|ó|ò|ò|ô|ô|õ|õ)', 
    	'O' => '(o|ó|ó|ò|ò|ô|ô|õ|õ)', 
    	'u' => '(u|ú|ú|ù|ù|û|û)', 
    	'U' => '(u|ú|ú|ù|ù|û|û)', 
    	'ç' => '(c|ç|ç)', 
    	'c' => '(c|ç|ç)'
	);

    //Substituindo acentos
    $str = strtr($str, $map);

    //Substituindo vogais e ç para REGEXP
    $str = strtr($str, $regpx);

    //Substituindo espaços em branco
    $str = str_replace(' ', '|', $str);

    return ($str);
}
?>

Perceba que a primeira coisa que eu faço é substituir as vogais com acentos para vogais comuns sem acento, com a função strtr() do PHP, que retorna uma string cópia da que é passada como primeiro parâmetro, substituindo todas as ocorrências contidas no array passado no segundo parâmetro, simples assim. Depois substituo as vogais por comandos para o REGEXP. Por fim substituo os espaços em branco por “|”, para que se o usuário digitar: “quero pão” a função retorne:
“q(u|ú|ú|ù|ù|û|û)r(o|ó|ó|ò|ò|ô|ô|õ|õ)|p(a|á|á|à|à|â|â|ã|ã)(o|ó|ó|ò|ò|ô|ô|õ|õ)”

Ficou grande né? Maior ainda ficaria se estivesse usando vários likes.

Mas pera ai, como vou fazer para aplicar isso à minha consulta? Simples:

$pesquisa = mysql_query('SELECT * FROM USUARIO WHERW NOME REGEXP "'.trataPesquisa($suaPesquisa).'"');

 
Pronto pessoal, é isso, qualquer dúvida deixe um comentário que eu terei prazer em responder. Obrigado!
 
[ads1]

Jayr Alencar

Doutorando em Ciências da Computação no Centro de Informática da Universidade Federal do Pernambuco (CIn - UFPE); Mestre pela mesma instituição; Formado em Análise e Desenvolvimento de Sistemas; Católico; Fã de O Senhor do Anéis.

Você pode gostar...

1 Resultado

  1. Renan Hideki Kariyazaki disse:

    Obrigado esse tutorial me ajudou.

Deixe um comentário para Renan Hideki Kariyazaki Cancelar resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *