Problema com acentos - curiosidade

11 respostas
L

Estava procurando algum método em Java que fizesse a ‘normalização’ de uma String. Algo como trocar a letra acentuada pela letra normal.
Achei dois métodos, mas nenhum dos dois funcionou, até que um terceiro funcionou, mas não entendi o porquê. Gostaria
que me explicassem porque os dois não funcionaram e como essa coisa estranha que é o terceiro funciona.

1º modo: Retorna o nome sem alteração alguma

public class Metodo {
	
	public static String normalizar(String nome){
		

		
		nome = nome.replaceAll("é,è,ê,ë", "e");
		nome = nome.replaceAll("á,à,ä,â,ã", "a");
		nome = nome.replaceAll("ú,ù,ü,û", "u");
		nome = nome.replaceAll("ó,ò,ô,õ,ö", "o");
		nome = nome.replaceAll("í,ì,ï,î", "i");
		nome = nome.replaceAll("ç", "c");
		
        System.out.println(nome);
		
		return nome;
	}

}

2º modo: Funciona assim: Se digito ‘á’, ele retorna ‘?’. Obviamente essa não é a intenção

public class Metodo {
	
	public static String normalizar(String nome){
		
		  novoNome =  Normalizer.normalize(nome, Normalizer.Form.NFKD);
}

3º modo: Funciona perfeitamente, mas não entendi esse parâmetro do método ‘replaceAll’

import java.text.Normalizer;


public class Metodo {
	
	public static String normalizar(String nome){
		
		  return Normalizer.normalize(nome, Normalizer.Form.NFKD).replaceAll("\p{InCombiningDiacriticalMarks}+", "");  
		
	
	}

}

Agradeço a quem puder ajudar.

11 Respostas

rogelgarcia

1 - Voce está passando como parametro o nome com letras maiusculas? Esse algoritmo só substitui as minusculas

2 - Nao sei o que faz esse normalizer… mas pode ser problemad e charset (chute)

3 - Tb nao sei

Poneis123

Recomendo dar uma lida na api da Normalizer… pode ser q encontre algo… não pude ler ainda(falta de tempo).

http://java.sun.com/javase/6/docs/api/java/text/Normalizer.html#normalize(java.lang.CharSequence,%20java.text.Normalizer.Form)

T

1º método - Utilize dessa maneira, e não com vírgulas.

nome = nome.replaceAll("[éèêë]", "e");
nome = nome.replaceAll("[áàäâã]", "a");
nome = nome.replaceAll("[úùüû]", "u");
nome = nome.replaceAll("[óòôõö]", "o");
nome = nome.replaceAll("[íìïî]", "i");
nome = nome.replaceAll("ç", "c");

EDIT: Adicione também as letras maiúsculas entre os colchetes.

Os outros dois métodos também não sei rsrs

rogelgarcia

Tiago Borghi:
1º método - Utilize dessa maneira, e não com vírgulas.

nome = nome.replaceAll("[éèêë]", "e");
nome = nome.replaceAll("[áàäâã]", "a");
nome = nome.replaceAll("[úùüû]", "u");
nome = nome.replaceAll("[óòôõö]", "o");
nome = nome.replaceAll("[íìïî]", "i");
nome = nome.replaceAll("ç", "c");

EDIT: Adicione também as letras maiúsculas entre os colchetes.

Os outros dois métodos também não sei rsrs

Boa Tiago… nem tinha prestado atençao :smiley: valew

ViniGodoy

Se quiser entender a fundo o que o Normalizer faz:
http://www.unicode.org/reports/tr15/tr15-23.html

O padrão unicode tem um tipo de caracter especial chamado diacritical mark. É um caracter de acentuação, mas que pode ser digitado após a letra e, quando um editor o reconhece, ele “volta atrás” no desenho da letra anterior e insere o caracter. Esse caracter é muito usada por esses reconhecimentos de palavras de palms, onde vc digita primeiro a letra, e depois a critical mark.

Pois bem, quando o normalizer pega uma letra como ö ou ç, ele transforma isso no conjunto de letras apropriado. Algumas letras podem se transformar em conjuntos de duas letras, ou conjuntos de letras seguidos da diacrítical mark, por exemplo, oe no caso do ö e c’ no caso do ç. Aquele ’ é a diacritical mark.

A regex do segundo parâmetro pede justamente para remover todas as diacritical marks.

rogelgarcia

ViniGodoy:
Se quiser entender a fundo o que o Normalizer faz:
http://www.unicode.org/reports/tr15/tr15-23.html

O padrão unicode tem um tipo de caracter especial chamado diacritical mark. É um caracter de acentuação, mas que pode ser digitado após a letra e, quando um editor o reconhece, ele “volta atrás” no desenho da letra anterior e insere o caracter. Esse caracter é muito usada por esses reconhecimentos de palavras de palms, onde vc digita primeiro a letra, e depois a critical mark.

Pois bem, quando o normalizer pega uma letra como ö ou ç, ele transforma isso no conjunto de letras apropriado. Algumas letras podem se transformar em conjuntos de duas letras, ou conjuntos de letras seguidos da diacrítical mark, por exemplo, oe no caso do ö e c’ no caso do ç. Aquele ’ é a diacritical mark.

A regex do segundo parâmetro pede justamente para remover todas as diacritical marks.

Como diria um colega meu: Esse cara tem o dom! :lol:

ViniGodoy

Na verdade, eu tinha era um palm… :lol:

L

rogelgarcia:
1 - Voce está passando como parametro o nome com letras maiusculas? Esse algoritmo só substitui as minusculas

2 - Nao sei o que faz esse normalizer… mas pode ser problemad e charset (chute)

3 - Tb nao sei

Na minha outra classe tem um método .toDownCase();

Mas obrigado por responder mesmo assim

L

Tiago Borghi:
1º método - Utilize dessa maneira, e não com vírgulas.

nome = nome.replaceAll("[éèêë]", "e");
nome = nome.replaceAll("[áàäâã]", "a");
nome = nome.replaceAll("[úùüû]", "u");
nome = nome.replaceAll("[óòôõö]", "o");
nome = nome.replaceAll("[íìïî]", "i");
nome = nome.replaceAll("ç", "c");

EDIT: Adicione também as letras maiúsculas entre os colchetes.

Os outros dois métodos também não sei rsrs

Obrigado pela resposta

L

ViniGodoy:
Se quiser entender a fundo o que o Normalizer faz:
http://www.unicode.org/reports/tr15/tr15-23.html

O padrão unicode tem um tipo de caracter especial chamado diacritical mark. É um caracter de acentuação, mas que pode ser digitado após a letra e, quando um editor o reconhece, ele “volta atrás” no desenho da letra anterior e insere o caracter. Esse caracter é muito usada por esses reconhecimentos de palavras de palms, onde vc digita primeiro a letra, e depois a critical mark.

Pois bem, quando o normalizer pega uma letra como ö ou ç, ele transforma isso no conjunto de letras apropriado. Algumas letras podem se transformar em conjuntos de duas letras, ou conjuntos de letras seguidos da diacrítical mark, por exemplo, oe no caso do ö e c’ no caso do ç. Aquele ’ é a diacritical mark.

A regex do segundo parâmetro pede justamente para remover todas as diacritical marks.

Muito obrigado. Mais claro que isso, impossível.

Kleber-rr

Olá pessoal, td bem?? Estou querendo utilizar o método normalize para pesquisa em um banco.

Ou seja, quando o usuario digitar o nome "joao", ele me retorne a lista com o "joao" e com o "joão".

Meu método de busca está assim:
public List<Funcionario> getFuncionariosGenerico() {
		Session session = HibernateUtil.currentSession();
		FuncionarioDao funcionarioDao = new FuncionarioDao(session,
				Funcionario.class);
		List<Funcionario> lista = funcionarioDao.pesquisaFuncionarios(
				this.funcionario.getNome(), this.funcionario.getCpf(),
				this.funcionario.getRg());

		return lista;
	}
No Dao está assim:
@SuppressWarnings("unchecked")
	public List<Funcionario> pesquisaFuncionarios(String nome, String cpf,
			String rg) {
		Criteria c = session.createCriteria(Funcionario.class);
		List<Funcionario> results = new ArrayList<Funcionario>();
		c.add(Restrictions.like("nome", nome, MatchMode.ANYWHERE));
		c.add(Restrictions.like("cpf", cpf, MatchMode.ANYWHERE));
		c.add(Restrictions.like("rg", rg, MatchMode.ANYWHERE));
		results = (List<Funcionario>) c.list();
		return results;
	}

Agradeço a ajuda.

Criado 26 de março de 2010
Ultima resposta 11 de ago. de 2010
Respostas 11
Participantes 6