Jump to content
Fórum Script Brasil
  • 0

Busca Por Fonemas


Denis Courcy

Question

Ontem, no final do dia, comentei que colocaria aqui no forum uma função que realiza busca por fonemas.

Esta função foi traduzida do delphi (e melhorada) de uma edição da revista ClubeDelphi.

Ela permite que se busque variações de um mesmo nome, talcomo FELIPE, FILIPE, PHILIP, etc.

Os fonemas aqui descritos são diferentes dos fonemas da função SOUNDEX (nativa do MySQL), isto porque a função SOUNDEX utiliza fonemas oriundos do Inglês e nesta função usamos fonemas do portugûes (Brasil).

O ideal é incluir um campo tipo varchar(25) (com indice para este campo) na tabela onde as pesquisas serão mais constantes.

Na inclusão Carrege o campo com CodFonPT_BR(@nome) e na pesquisa utilize na cláusula WHERE campo = CodFonPT_BR(@nome)

Por possuir duas aplicações (diferentes, escritas com linguagens) que buscam informações no mesmo banco obtive vantagem de colocar em um só lugar fazer a manutenção do que é comum aos dois sistemas.

Espero que gostem.

att

Denis Courcy.

PS. A Listagem da função está logo abaixo:

DELIMITER $$;

DROP FUNCTION IF EXISTS `MEUBANCO`.`CodFonPT_BR`$$

CREATE DEFINER=`root`@`localhost` FUNCTION `CodFonPT_BR`(nome char(50)) RETURNS char(50) CHARSET latin1
BEGIN
   declare novo char(50);
   declare auxiliar char(50);
   declare aux char(1);
   declare aux_ant char(1);
   declare aux_pos char(1);
   declare x int default 0;
   declare y int default 0;
   set novo = '';
   set auxiliar = '';
   set nome = UCase(nome);
   /*Tira acentos e cedilha*/
   set x = 1;
   while x <= Length(nome) do
       set aux = substring(nome, x, 1);
       if aux in ('Á', 'À', 'Â', 'Ä', 'Ã') then
          set aux = 'A';
       elseif aux in ('É', 'È', 'Ê', 'Ë') then
          set aux = 'E';
       elseif aux in ('Í', 'Ì', 'Î', 'Ï') then
          set aux = 'I';
       elseif aux in ('Ó', 'Ò', 'Ô', 'Ö', 'Õ') then
          set aux = 'O';
       elseif aux in ('Ú', 'Ù', 'Û', 'Ü') then
          set aux = 'U';
       elseif aux = 'Ç' then
          set aux = 'C';
       elseif aux = 'não' then
          set aux = 'N';
       elseif aux = ' ' then
          set y = 1;
       elseif Ord(aux) > 127 then
          set aux = char(32);
       end if;
       if y = 1 and aux <> ' ' then
          set auxiliar = concat(auxiliar, ' ', aux);
          set y = 0;
       else
          set auxiliar = concat(auxiliar, aux);
       end if;
       set x = x + 1;
   end while;
   /*
         Retira E, DA, DAS, DE, DI, DO, DOS do nome. Exemplo:
         Jos? da Silva = Jose Silva;
         Jo?o Costa e Silva = Joao Costa Silva
   */
   set x = instr(auxiliar, ' DA ');
   while x > 0 do
      set auxiliar = concat(substring(auxiliar, 1, x), substring(auxiliar, x + 4, 50));
      set x = instr(auxiliar, ' DA ');
   end while;
   set x = instr(auxiliar, ' DAS ');
   while x > 0 do
      set auxiliar = concat(substring(auxiliar, 1, x), substring(auxiliar, x + 5, 50));
      set x = instr(auxiliar, ' DAS ');
   end while;
   set x = instr(auxiliar, ' DE ');
   while x > 0 do
      set auxiliar = concat(substring(auxiliar, 1, x), substring(auxiliar, x + 4, 50));
      set x = instr(auxiliar, ' DE ');
   end while;
   set x = instr(auxiliar, ' DI ');
   while x > 0 do
      set auxiliar = concat(substring(auxiliar, 1, x), substring(auxiliar, x + 4, 50));
      set x = instr(auxiliar, ' DI ');
   end while;
   set x = instr(auxiliar, ' DO ');
   while x > 0 do
      set auxiliar = concat(substring(auxiliar, 1, x), substring(auxiliar, x + 4, 50));
      set x = instr(auxiliar, ' DO ');
   end while;
   set x = instr(auxiliar, ' DOS ');
   while x > 0 do
      set auxiliar = concat(substring(auxiliar, 1, x), substring(auxiliar, x + 5, 50));
      set x = instr(auxiliar, ' DOS ');
   end while;
   set x = instr(auxiliar, ' E ');
   while x > 0 do
      set auxiliar = concat(substring(auxiliar, 1, x), substring(auxiliar, x + 3, 50));
      set x = instr(auxiliar, ' E ');
   end while;
   /*         
      Retira letras duplicadas. Exemplo Elizabette = Elizabete
   */
   set x = 1;
   while x < length(auxiliar) do
      set aux     = substring(auxiliar, x, 1);
      set aux_pos = substring(auxiliar, x + 1, 1);
      if aux = aux_pos then
         set auxiliar = concat(substring(auxiliar,1, x),substring(auxiliar,x + 2, 50));
      end if;
      set x = x + 1;
   end while;
   set x = 1;
   while x <= length(auxiliar) do
      if x > 1 then
         set aux_ant = substring(auxiliar, x - 1, 1);
      else 
         set aux_ant = '';
      end if;
      if x < length(auxiliar) then
         set aux_pos = substring(auxiliar, x + 1, 1);
      else
         set aux_pos = '';
      end if;
      set aux = substring(auxiliar, x, 1);
      /*
           'A','E','I','O','U','Y','H' e espaços - ignora
      */
      case
         when aux in ('B','D','F','J','K','L','M','N','R','T','V','X') then
            set novo = concat(novo, aux);
         when aux = 'C' then
            if aux_pos = 'H' then /*CH = X*/
               set novo = concat(novo, 'X');
            elseif aux_pos in ('A', 'E', 'O', 'U') then /* Carol = Karol */
               set novo = concat(novo, 'K');
            else /*Celina = Selina, Cintia = Sintia*/
               set novo = concat(novo, 'S');
            end if;
         when aux = 'G' then /* Geferson = Jeferson */
            if aux_pos in ('E', 'I') then
               set novo = concat(novo, 'J'); 
            else
               set novo = concat(novo, 'G');
            end if;
         when aux = 'P' then /*Phelipe = Felipe*/
            if aux_pos = 'H' then
               set novo = concat(novo, 'F');
            else
               set novo = concat(novo, 'P');
            end if;
         when aux = 'Q' then /* Keila = Queila */
            if aux_pos = 'U' then
               set novo = concat(novo, 'K');
            else
               set novo = concat(novo, 'Q');
            end if;
         when aux = 'S' then
            if aux_pos = 'H' then /*SH = X*/
               set  novo = concat(novo, 'X');
            elseif aux_pos in ('A','E','I','O','U') then /*S entre duas vogais = Z*/
               if aux_ant in ('A','E','I','O','U') then
                  set novo = concat(novo, 'Z');
               else
                  set novo = concat(novo, 'S');
               end if;
            end if;
         when aux = 'W' then /* Walter = Valter */
            set novo = concat(novo, 'V');
         when aux = 'Z' then /*no final do nome tem som de 'S' -> Luiz = Luis */
            if (x = length(auxiliar)) or (aux_pos = ' ') then
               set novo = concat(novo, 'S');
            else
               set novo = concat(novo, 'Z');
            end if;
         else
            if x = 1 then
               if aux ='Y' then /* Ivan = Yvan*/
                  set novo = concat(novo, 'I');
               elseif aux = 'H' then /*Heber = Eber */
                  set novo = concat(novo, aux_pos);
               else /* primeira letra igual a 'A','E','I','O' ou 'U' */
                  set novo = concat(novo, aux);
               end if;                  
            end if;
      end case;
      set x = x + 1;
   end while;
   return novo;
END$$

DELIMITER;$$

Link to comment
Share on other sites

2 answers to this question

Recommended Posts

  • 0

Criei em php traduzindo a sua lógica a função de retirar letras duplicadas, estou traduzindo a sua função de fonética também aí está:

function RetiraDuplicadas($auxiliar) {

$x = 0;

while ($x < strlen($auxiliar) ) {

$aux = substr($auxiliar, $x, 1);

$aux_pos = substr($auxiliar, $x + 1, 1);

if ( $aux == $aux_pos ) {

$auxiliar = substr($auxiliar,0, $x).substr($auxiliar,$x + 1, strlen($auxiliar)-1);

}

$x = $x + 1;

}

return $auxiliar;

}

Link to comment
Share on other sites

  • 0
Criei em php traduzindo a sua lógica a função de retirar letras duplicadas, estou traduzindo a sua função de fonética também aí está:

...

Legal você ter feito isso, 'castmetal'.

Parabéms pela iniciativa.

Quando coloquei a função a público foi com o intuito de divulgar que há mais de uma maneira de fazer coisas interessantes.

No caso específico desta função está a diponibilidade de ficar residente no banco de dados, além de facilitar a manutenção em casos de sistemas, como os meus, que estão em linguagens diferentes(também chamado de portabilidade).

Onde estão os sinais de "?" substitua por letras acentuadas Á, À, Â, Ã, Ä, É, È, Ê, Ë, Í, Ì, Î, Ï, Ó, Ò, Ô, Õ, Ö, Ú, Ù, Û, Ü, Ç e não.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.


  • Forum Statistics

    • Total Topics
      152.1k
    • Total Posts
      651.8k
×
×
  • Create New...