Retirando acentuação antes de inserir no banco de dados

22 respostas
P

Bom dia,
Estou fazendo um programa que antes de fazer a inserção no banco de dados seria necessário retirar todos os acentos. Me disseram q o replaceAll resolveria meu problema, mas eu fiz alguns testes e a frase com acentuação continuava mesma coisa…
Õbrigado,

Marco Paradiso

22 Respostas

Mauricio_Linhares

Você quer retirar os acentos e colocar o que?

rodrigo_gomes

talvez isso ajude

saoj

Quando for assim tenta fazer uma busca no forum antes.

Muitas questão já estão respondidas.

http://www.guj.com.br/posts/list/21142.java

dyorgio

tenho para mim que a maneira mais rapida é fazer um laço e um case dentro dele…tipo isso :

public String AcentoTirar(String as_original)
   String
    ls_retorno = "";
    for (int ln = 0 ; ln < as_original.length() ; ln ++ ){
          switch (as_original.charAt(ln)){
                  case      'á':
                  case      'à':
                  case      'ã':
                  case      'ä':
                  case      'â':
                   {
                               ls_retorno += "a";
                               break;
                    }
                   case      'é':
                  case      'è':
                  case      'ê':
                  case      'ë':
                   {
                               ls_retorno += "e";
                               break;
                    }
                  case      'í':
                  case      'ì':
                  case      'ï':
                  case      'î':
                   {
                               ls_retorno += "i";
                               break;
                    }
                    case      'ó':
                  case      'ò':
                  case      'õ':
                  case      'ö':
                  case      'ô':
                   {
                               ls_retorno += "o";
                               break;
                    }
                    case      'ú':
                  case      'ù':
                  case      'ü':
                  case      'û':
                   {
                               ls_retorno += "u";
                               break;
                    }
                    default :
                     {
                               ls_retorno += as_original.charAt(ln);
                        }

           }
   }
return ls_retorno;
}

desculpem-me pela identação…mas acho que esta faltando aqui no forum do guj o suporte as TAB!!!

espero ter ajudado…o método se torna grande…mas é estremamente mais rapido do que o String.replaceAll()!!!

[]'s dyorgio

cv1

dyorgio, “é” eh diferente de “e”. Pq fingir que ainda estamos em 1973 e nao usar unicode? :slight_smile:

Mauricio_Linhares

Ora, porque todo mundo quer encher a cabeça de problemas quando vão enviar as informações de um programa Java pra um banco de dados :lol:

Tem algum banco que ainda não dá suporte a Unicode?

fredferrao

Me corrijam c eu estiver errado!! Mas eh justamente este o problema!! pois o usuario pode cadastrar tanto JOSÉ quanto JOSE, e ai na hora de fazer uma pesquisa ele tambem pode digitar tanto JOSÉ como JOSE, e ai ja viu a zebra, certos registros nao irao aparecer!! E vai tentar colocar na cabeça do usuario que ele deve acentuar corretamente ou nao usar o acento!!1

OBS. pelo menos no Firebird ele nao reconhece josé como jose!!!

dyorgio

bem a resposta é rapida e fácilll…
permitir que o usuario insira informações no banco acentuadas
prejudica e muito a pesquisa dessa mesma informação depois…
pois tem analfabeto que não sabe escrever as palavras corretamente(acentuadas)…e tem aqueles que não querem…

claro que isso é apenas para colunas que serão constantemente pesquisadas…

[]'s dyorgio

_fs

Deve ter um jeito melhor, mas esse aqui faz o serviço:

temp = temp.replaceAll( "([á|à|â|ã])", "a" )
					.replaceAll( "([Á|À|Â|Ã])", "A" )
					.replaceAll( "([é|è|ê])", "e" )
					.replaceAll( "([É|È|Ê])", "E" )
					.replaceAll( "([í|ì|î])", "i" )
					.replaceAll( "([Í|Ì|Î])", "I" )
					.replaceAll( "([ó|ò|ô|õ])", "o" )
					.replaceAll( "([Ó|Ò|Ô|Õ])", "O" )
					.replaceAll( "([ú|ù|û|û])", "u" )
					.replaceAll( "([Ú|Ù|Û|Û])", "U" );
aborges

Boa LIPE!

Pensei em algo assim:

public static Object formatValue(Object value){
		if(value!=null && value instanceof String){
			String strValue = (String)value;
			strValue = strValue.toUpperCase();
			if(strValue.equals("?")){
				strValue="";
			}else{
				String mask = "ÃÕÀÈÌÒÙÁÉÍÓÚÄËÏÖÜÂÊÎÔÛÇ";
				String correct = "AOAEIOUAEIOUAEIOUAEIOUC";
				for(int c=0;c< mask.length();c++){
					strValue = strValue.replaceAll(mask.substring(c,c+1),correct.substring(c,c+1));
				}
			}
			value = strValue;
		}
		
		return value;
	}

Mas com Regular Expression fica mais legal!

cv1

Gente, voces estao confundindo armazenamento de dados com busca de dados. Essas coisas, apesar de estarem geralmente controladas pela mesma coisa (o “BAAAAAANCO de dados” - diga isso com voz aterrorizante).

Praticamente todos os bancos que eu conheco tem suporte a alguma funcao do tipo soundex(), que faz pesquisa fonetica. Pra que fazer essas gambiarras nojentas? :?

_fs

cv, nem todo campo é verdejante como na ThoughWorks :smiley:

cv1

Complementinho:

No MySQL voce pode fazer ateh isso aqui oh:

SELECT * FROM Usuarios u WHERE u.nome SOUNDS LIKE ?

Nao fica bonitinho? :smiley:

http://dev.mysql.com/doc/mysql/en/string-functions.html

dyorgio

bem meu amigos…
claro que a minha implementação do método que ytira acentos é um pouco…
vamos dizer…tosca(primaria)…porém repito que é a maneira mais rapida de fazer isso…
para quem conhece a linguagem java a fundo…(código fonte da classe String)…
sabe que o método ReplaceAll() chama pelo menos 20 métodos em cascata e
instancias uns 40 Objetos…
tudo isso para fazer uma pesquisa bem refinada…
por isso levando em consideração que essa funcionalidade(retirada de acentos) será ultilizada com muita frequencia…
usem o laço com o case :wink:
O pessoal aqui realmente gosta de mostrar que sabe fazer o serviço…
mas não se usa um trator pra carregar um punhado de areia!!!
não concordam?!?!?!
[]'s dyorgio

cv1

Concordo, e por isso mesmo a pesquisa pelo metodo soundex eh muito mais eficiente.

dyorgio

cv : Concordo, e por isso mesmo a pesquisa pelo metodo soundex eh muito mais eficiente.

como!!! rapaz…isso é pratico…não tem melhor desempenho
nem daqui a 1000 anos!!!
tem loco pra tudo
[]'s dyorgio

_fs

hehe não ia falar nada cara … mas depois do seu “quem conhece a fundo” … melhor aprender que concatenação de strings é lento pra burro, e, se não me engano, 3 objetos são criado pra fazer s += “a” hehe

E quanto a campeonatinho de código mais rápido, fazendo algumas pequenas modificações no código do colega, ganhou do meu de loooonge e do seu código 100% mais rápido (arrumei pra cobrir maiusculas também). Testei com 500k repetições. Sem contar que não tem o seu elegantérrimo switch hehe

static String mask = "áàâãäéèêëëíìîîîóòôõöúùûüü";
	static String maskUpper = mask.toUpperCase();
	static String correct = "aeiou";
	static String correctUpper = correct.toUpperCase();
	public static String formatValue( String formatted )
	{
		int index = -1;

		for( int i = 0; i < formatted.length(); i++ )
		{
			if( ( index = mask.indexOf( formatted.charAt( i ) ) ) >= 0 )
				formatted = formatted.replace( formatted.charAt( i ), correct.charAt( index / 5 ) );
			else if( ( index = maskUpper.indexOf( formatted.charAt( i ) ) ) >= 0 )
				formatted = formatted.replace( formatted.charAt( i ), correctUpper.charAt( index / 5 ) );
		}

		return formatted;
	}

E não conhecia essa sintaxe que usou no switch, valeu pela dica!

ps.: http://java.sun.com/docs/codeconv

cv1

Nao vou nem entrar na discussao do algoritmo que o Lipe implementou (e que, por sinal, tem uma implementacao bem enxutinha, mas ainda assim dava pra se livrar do foo e fooUpper, usando uma String so).

Basta dizer que esse algoritmo eh ineficiente para o proposito que vc ta tentando implementar, que eh tornar a pesquisa de informacoes e nomes proprios numa base de dados o mais eficiente e tolerante a erros de grafia possivel. Basta dizer que, nesse algoritmo, “Luiz” e “Luis” continuam sendo diferentes.

Eis uma descricao do Soundex, com implementacoes de referencia:

http://www.creativyst.com/Doc/Articles/SoundEx1/SoundEx1.htm

No Commons-Codec da Jakarta ja tem implementacoes nao so do Soundex, mas de outros algoritmos, potencialmente mais eficientes que ele.

http://jakarta.apache.org/commons/codec/apidocs/org/apache/commons/codec/language/Soundex.html
http://jakarta.apache.org/commons/codec/apidocs/org/apache/commons/codec/language/Metaphone.html
http://jakarta.apache.org/commons/codec/apidocs/org/apache/commons/codec/language/RefinedSoundex.html
http://jakarta.apache.org/commons/codec/apidocs/org/apache/commons/codec/language/DoubleMetaphone.html

dyorgio

Não entendi Lipe…
esse que você apresentou é o mais rapido?
[]'s dyorgio

cv1

Eh mais rapido, nao o mais rapido. Mas isso nao vem ao caso - leia meu post anterior.

Sami_Koivu

Entrando no campeonatinho! :smiley: Vou indo atrás dos premios “O Mais Rápido” e “O Mais Totalmente Feio” :wink:

Só demonstrando que o case-switch realmente tem a capasidade de estar bem rápido. Isso deve a instrução tableswitch do java bytecode:
http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions2.doc14.html

Mas… fora dessa brincadeira, pessoalmente, se eu tivesse fazer uma sistema dessas, eu provavelmente tomaria o caminho indicado pelo CV.

-Sami

Opa… quase esqueci… meu candidato:

public static String tirarAcentos(String original) {
        char[] array = original.toCharArray();
        for (int ln = 0; ln < array.length; ln++) {
            char c = array[ln];
            switch (c) {
                case 'á':
                case 'à':
                case 'ã':
                case 'ä':
                case 'â':
                    array[ln] = 'a';
                    break;
                case 'À':
                case 'Á':
                case 'Ã':
                case 'Ä':
                case 'Â':
                    array[ln] = 'A';
                    break;
                case 'é':
                case 'è':
                case 'ê':
                case 'ë':
                    array[ln] = 'e';
                    break;
                case 'É':
                case 'È':
                case 'Ê':
                case 'Ë':
                    array[ln] = 'E';
                    break;
                case 'í':
                case 'ì':
                case 'ï':
                case 'î':
                    array[ln] = 'i';
                    break;
                case 'Í':
                case 'Ì':
                case 'Ï':
                case 'Î':
                    array[ln] = 'I';
                    break;
                case 'ó':
                case 'ò':
                case 'õ':
                case 'ö':
                case 'ô':
                    array[ln] = 'o';
                    break;
                case 'Ó':
                case 'Ò':
                case 'Õ':
                case 'Ö':
                case 'Ô':
                    array[ln] = 'O';
                    break;
                case 'ú':
                case 'ù':
                case 'ü':
                case 'û':
                    array[ln] = 'u';
                    break;
                case 'Ú':
                case 'Ù':
                case 'Ü':
                case 'Û':
                    array[ln] = 'U';
                    break;
                default:
                    array[ln] = c;
            }
        }
        return new String(array);
    }
rfs1970

Desculpe CV, mas eu tive que me registrar no site apenas para registrar o meu ponto de vista sobre o soundex

1o) Se a sua base de dados for grande, o tempo de pesquisa será infernalmente maior (imagine a pesquisa em um banco de dados de endereco com 700 mil registros)

2o) O soundex funciona muito bem para o idioma ingles, tipo : wood and wody, mas para outros idiomas nem sempre o resultado é o esperado

Retirado do site do Mysql:

Important: When using SOUNDEX(), you should be aware of the following limitations:

* This function, as currently implemented, is intended to work well with strings that are in the English language only. Strings in other languages may not produce reliable results.
* This function is not guaranteed to provide consistent results with strings that use multi-byte character sets, including utf-8.
Criado 7 de junho de 2005
Ultima resposta 27 de jul. de 2007
Respostas 22
Participantes 11