1

PE8OU¡8A COM ACENTO8 DENTRO DO MY8OL
Diego M. Rodrigues (diego@drsolutions.com.br)


O objetivo desse material é mostrar aos desenvolvedores da comunidade PHP como realizar
buscas dentro de tabelas MySQL quando o conteúdo dos campos contém textos acentuados.

Um exemplo típico seria dentro de uma loja virtual de livros, buscar livros baseado no título dos
mesmos.

Vamos imaginar que nosso visitante queira buscar o livro “PHP: A Bíblia”. Temos dois
problemas com o acento “í” aqui. O primeiro é como isso está cadastrado no banco de dados,
pois podemos ter “PHP: A Bíblia”, “PHP: A Biblia” e ainda “PHP: A Bíblia” (caso tenha
sido passado um html_entities() na rotina de inclusão).

O segundo problema está no formulário que o visitante vai preencher para realizar a busca, pois
ele pode escrever “bíblia”, “biblia" , “BLÍBLIA”, “biblia" e por aí vai... se passarmos um
html_entities() no conteúdo do que foi informado pelo usuário, essas coisas ainda poderiam virar
algo como “bíblia”...

A forma mais básica de realizarmos buscas de “pedaços” de campos dentro de uma tabela é
usando a cláusula LIKE do SQL. Por exemplo:

SELECT * FROM livros WHERE titulo LIKE "%bíblia%¨

Essa query irá retornar os registros da tabela livros que dentro do título exista a palavra
“bíblia”... mas note que irá busca “bíblia”, e não “biblia’ e nem “bíblia”, portanto se
nosso visitante buscasse por “biblia” não encontraria o livro “PHP: A Bíblia”.

A cláusula LIKE, embora muito útil em diversos casos, deixa muito a desejar quanto estamos
lidando em buscas dentro de textos na língua portuguesa. Uma boa alternativa é o uso de
Expressões Regulares usando a cláusula REGEXP.

A primeira pergunta que surge é: “O que são expressões regulares?”
“Bem resumido, uma expressão regular é um método formal de se especificar um padrão de
texto.” (Aurélio Marinho Jargas)

A segunda seria: “Você pode me dar um exemplo?”
Poderíamos usar uma ER(expressão regular) para realizar buscas do tipo:
Todos os títulos que comecem com “PHP”
Todos os títulos que terminem com “invadir”
Todos os títulos que contenham “b” seguido de “i” ou “ì” ou “í” seguido de “blia”

Esse artigo não visa explicar as ERs em si, mas como usá-las. Irei apenas introduzir alguns
conceitos básicos a seguir e disponibilizarei links no final do artigo para os mais interessados.

Vamos lá, um pouco de ERs:
“$” quer dizer começo de uma linha
“^” quer dizer final de uma linha
“.” quer dizer qualquer coisa
“(a|b)” quer dizer a OU b
2
“(1|2|3)” quer dizer 1 OU 2 OU 3
“*” quer dizer tanto faz

Com isso já posso dar alguns exemplos:
“$php” linha que comece com “php”
“$p.p” linha que comece com “p” seguido “um caractere qualquer” seguido de “p”, poderia ser
php, p2p, pgp...
“p(h|g)p^” linha que termina com “php” ou “pgp”

As ERs são muito mais do que essas poucas regras que eu passei. Os leitores mais atentos já
devem estar percebendo como elas podem ser poderosas... Mais alguns exemplos:
Pegar uma data dentro de uma página
Validar um e-mail
Pegar a cotação do dólar

Voltando ao tema do artigo, vamos ver como usar uma ER dentro do MySQL. Vamos realizar a
busca: todos os livros que o título comece com “php”:

SELECT * FROM livros WHERE titulo REGEXP "$php¨

Outra busca seria, todos os livros que contenham a palavra php ou pgp:

SELECT * FROM livros WHERE titulo REGEXP "p(h|g)p¨

Voltando ao nosso primeiro exemplo, vamos buscar “bíblia” ou “biblia” ou “bíblia”... na
verdade vamos buscar uma palavra que comece com “b”, tenha “i” ou “í” ou “iacute;”, e depois
“blia”:

SELECT * FROM livros WHERE titulo REGEXP "b(i|í|í)blia¨

E se estivermos falando da palavra “ação”, o usuário pode digitar “acao”, “açao”, “ação”...
vamos então montar uma ER para o “ç” e para o “ã”:

SELECT * FROM livros WHERE titulo REGEXP "a(c|ç|ç)(a|ã|ã)o¨

Aí vem a terceira pergunta: “Como adivinhar onde estão os acentos para montar a ER?”
Não dá meu amigo, o jeito é montar uma ER bem abrangente, pois é melhor o visitante receber
uma lista com alguns livros a mais do que a menos...

A minha proposta é a seguinte: Pegue o que o usuário digitou e remova os acentos, depois
busque todas as possibilidades com acentos e sem acentos... por exemplo, se o usuário digitar
“acao”, “açao” ou “ação”, vamos transformar em “acao".

Agora vamos pensar.. “a” pode ser “a”, “ã”, “á”, “à”... “c” pode ser “c” ou “ç”... “o” pode ser
“o”, “õ”, “ó”, “ó”... Montando a ER:

SELECT * FROM livros WHERE titulo REGEXP "(a|ã|á|à)(c|ç)(a|ã|á|à)(o|õ|ó|ò)¨

Vocês já devem ter sentido como uma expressão dessas pode ficar grande. Eu uso o seguinte
apenas para a letra “a”:
(a|ã|á|à|ä|â|ã|á|à|ä|â|Ã|Á|À|Ä|Â|Ã|Á|&Ag
rave;|Ä|Â)

3
A quarta e última pergunta seria: “Você não tem aí uma funçãozinha pronta para montar essas
ERs?”
Sim tenho. Ela funciona da seguinte maneira: Primeiro converte tudo para minúsculo, depois tira
todos os acentos e por último monta a ER.

function stringParaBusca($str) {
//Transformando tudo em minúsculas
$str = trim(strtolower($str));

//Tirando espaços extras da string... "tarcila almeida" ou "tarcila almeida" viram "tarcila almeida"
while ( strpos($str," ") )
$str = str_replace(" "," ",$str);

//Agora, vamos trocar os caracteres perigosos "ã,á..." por coisas limpas "a"
$caracteresPerigosos =
array("ã","á","à","ä","â","é","è","ë","ê","í","ì","ï","î","õ","ó","ò","ö","ô","ú","ù","ü","û","ç");
$caracteresLimpos =
array("a","a","a","a","a","e","e","e","e","i","i","i","i","o","o","o","o","o","u","u","u","u","u");
$str = str_replace($caracteresPerigosos,$caracteresLimpos,$str);

//Agora que não temos mais nenhum acento em nossa string, e estamos com ela toda em "lower",
//vamos montar a expressão regular para o MySQL
$caractresSimples = array("a","e","i","o","u","c");
$caractresEnvelopados = array("{[a]}","{[e]}","{[i]}","{[o]}","{[u]}","{[c]}");
$str = str_replace($caractresSimples,$caractresEnvelopados,$str);
$caracteresParaRegExp = array(

"(a|ã|á|à|ä|â|ã|á|à|ä|â|Ã|Á|À|Ä|Â|Ã|Á|À|Ä|Â)",
"(e|é|è|ë|ê|é|è|ë|ê|É|È|Ë|Ê|É|È|Ë|Ê)",
"(i|í|ì|ï|î|í|ì|ï|î|Í|Ì|Ï|Î|Í|Ì|Ï|Î)",

"(o|õ|ó|ò|ö|ô|õ|ó|ò|ö|ô|Õ|Ó|Ò|Ö|Ô|Õ|Ó|Ò|Ö|Ô)",
"(u|ú|ù|ü|û|ú|ù|ü|û|Ú|Ù|Ü|Û|Ú|Ù|Ü|Û)",
"(c|ç|Ç|ç|Ç)" );
$str = str_replace($caractresEnvelopados,$caracteresParaRegExp,$str);

//Trocando espaços por .*
$str = str_replace(" ",".*",$str);

//Retornando a String finalizada!
return $str;
}

Poderíamos então usar essa função e montar uma query:
$sql = "SELECT * FROM livros WHERE titulo REGEXP \¨¨ . stringParaBusca("acao¨) . "\¨¨;
$result = mysql_query($sql);

Quem quiser um exemplo completo, pode pegar o arquivo ZIP:
http://www.drsolutions.com.br/exemplos/exemploregex.zip

Aos leitores mais interessados em expressões regulares, sugiro o site:
http://guia-er.sourceforge.net/guia-er.html

Aos leitores que desejam mais informações sobre como as ERs são usadas no MySQL, sugiro o
manual do MySQL:
http://dev.mysql.com/doc/refman/4.1/pt/regexp.html

Abraços a todos,
Diego M. Rodrigues
http://www.drsolutions.com.br
diego@drsolutions.com.br
diego.rodrigues@poli.usp.br

' . “c” pode ser “c” ou “ç”.. “ó”.“(1|2|3)” quer dizer 1 OU 2 OU 3 “*” quer dizer tanto faz Com isso já posso dar alguns exemplos: “$php” linha que comece com “php” “$p. “á”.$ % % % ' % % % ' .+( ) * % < +( % +7 8 9 : . p2p. o usuário pode digitar “acao”. pgp. Montando a ER: $ % % % '). ( *% < +( & . “o” pode ser “o”. A minha proposta é a seguinte: Pegue o que o usuário digitou e remova os acentos. “ã”. poderia ser php.+( ) * % & *% +( * % < 6 +( ) )' +( %< + * % 6 +( ) )% % % % % % < ..... ( -+ *' Aí vem a terceira pergunta: “Como adivinhar onde estão os acentos para montar a ER?” Não dá meu amigo... Mais alguns exemplos: Pegar uma data dentro de uma página Validar um e-mail Pegar a cotação do dólar Voltando ao tema do artigo.. pois é melhor o visitante receber uma lista com alguns livros a mais do que a menos. vamos então montar uma ER para o “ç” e para o “ã”: $%% ) * +$ % % ).. / 0 4 5 ( . “a” pode ser “a”.. “açao” ou “ação”. / 0 $%' ... na verdade vamos buscar uma palavra que comece com “b”. vamos ver como usar uma ER dentro do MySQL. tenha “i” ou “í” ou “iacute.. Os leitores mais atentos já devem estar percebendo como elas podem ser poderosas. vamos transformar em “acao". Vamos realizar a busca: todos os livros que o título comece com “php”: !# "" Outra busca seria. se o usuário digitar “acao”.. / 0 $ 1 2 3 Vocês já devem ter sentido como uma expressão dessas pode ficar grande. depois busque todas as possibilidades com acentos e sem acentos.( ) . “à”.p” linha que comece com “p” seguido “um caractere qualquer” seguido de “p”. vamos buscar “bíblia” ou “biblia” ou “b&iacute. “ação”. “açao”. “ó”. todos os livros que contenham a palavra php ou pgp: " #& " $%' Voltando ao nosso primeiro exemplo. “õ”. “p(h|g)p^” linha que termina com “php” ou “pgp” As ERs são muito mais do que essas poucas regras que eu passei. o jeito é montar uma ER bem abrangente. Eu uso o seguinte apenas para a letra “a”: $%%%%%% ..”.... e depois “blia”: $ % ) *' %( + E se estivermos falando da palavra “ação”.blia”.. por exemplo. Agora vamos pensar.

p & > Poderíamos então usar essa função e montar uma query: !W C !* C 6J WI *J ! W' W $ + q F > & ? )$ ) ' q + F Quem quiser um exemplo completo.+( ) * % & * % 6 +( ) )% % % % % % *% +( +( % +d e f g h ( .n ( ) .1/pt/regexp. Diego M.com. H/ H0 H4 H5 HK HL HM HN H GG HP G H1 H2 H3 HR HS HB HT HU HV H.com/doc/refman/4.br diego.br .* G D*G 6 H G %% %% %% $ .A quarta e última pergunta seria: “Você não tem aí uma funçãozinha pronta para montar essas ERs?” Sim tenho. pode pegar o arquivo ZIP: http://www. * E >F G ) &F F D# *$ " $ H G ' ! G ' ! C I * ) $ GGG! ' " *G H H + 6*.G 6G ) 6*.br diego@drsolutions.com.drsolutions. sugiro o site: http://guia-er.H) )** " *! ! * EH ' & "! + A A )> *" .H ' " *! ! ! + ! ) )** * E C & " J $ .rodrigues@poli.zip Aos leitores mais interessados em expressões regulares.G G ) 6*.html Aos leitores que desejam mais informações sobre como as ERs são usadas no MySQL.com. Rodrigues http://www.+( ) * % & * % *% +( +( 6 +( ) )'H % +G G % % % % % ) * % & * % 6 +( ) )% % % % % m ) * % m $ BTUV( +( +( % +i j k l ( +( & * % m 6 +( ) )'H +( % m +G G). * E & " JX ! ) ) * 6"* C J G GG GG H GG GGG+ $ H* H GG H H)' ! ) ) * >* ".G A< A& H 6 ) ) )** " & * G HF G" ) . / 0 4 5 ( .usp.C J G Y Z H@ * [GG Y [GG Y Z H@ Z H@ )[G+ $@ [GG Y Z H@ Z H@ [GG Y [GG YZ ' ! C I * ) $ ) ) * 6"* H) ) * > * " .+( ) * % & * % 6 +( ) )% % % % % % < . depois tira todos os acentos e por último monta a ER.+( ) * % < *% +( +( % +7 8 9 : . * 6 6 > > 6 )> * > *# * 6 > H * 6 )6 * &* A 6 6 > A * "* .+G' $%% % ) * % * ' + ! C I * ) $ ) ) * > * " .br/exemplos/exemploregex. " F ! C I * ) $ GG G! ' " * G HF H + A * >> A * >! + [ > = o.html Abraços a todos. ( *% < +( & * % < 6 +( ) )'H +( % < +G G* K L M N ( ) * % * $ %%% %% * +( & * % * 6 +( ) )% % % % % ) * % & * % 6 +( ) )'H +( % * +\ ] ^ _ ( +( +( % +G G % O% ( ) * % & * % 6 +() )%%%%% ) * % & * % 6 +( ) )'H $ % P% %Q +( +( % +`abc( +( +( % +G G %%%%%% $ 1 2 3 R S ( .' G G G ! ) )** 6" C J G GG GG GG GG GG GG GG GG GG H GG H GG GG GG GG GG GG GG GG GG GG G+ $ H H H H H* H* H* H* H GG H GG H H H H H H H H H H ' ! C I * ) $ ) )** * & " *! H) )** 6" H ' ! ! + A< A& W *> .+( ) ./F F 6" G G ! ) )** * & C J G GG GG GG GG GG GG GG GG GG HO G HQ G GG GG GG GG GG GG GG GG GGG+ $. Ela funciona da seguinte maneira: Primeiro converte tudo para minúsculo.mysql.sourceforge. sugiro o manual do MySQL: http://dev.* 6> ) 6 B ! C 6$ D*$ '+ ! ' A A > *" . => > ) > & ? ) $ '@ ! A A >= 6 > .net/guia-er.drsolutions.

Sign up to vote on this title
UsefulNot useful