如何在Java中规范化/淡化文本?我目前正在使用java.text.Normalizer:
Normalizer.normalize(str, Normalizer.Form.NFD)
.replaceAll("\\p{InCombiningDiacriticalMarks}+", "")
但它远非完美。例如,它保留挪威字符æ和ø不变。有没有人知道另一种选择?我正在寻找能够将各种语言的字符转换为a-z范围的东西。我意识到有不同的方法可以做到这一点(例如,应该将其编码为'a','e'或甚至'ae'?)并且我愿意接受任何解决方案。我宁愿不自己写点东西,因为我认为我不太可能为所有语言做得好。表现并不重要。
用例:我想将用户输入的名称转换为普通的a-z范围名称。转换后的名称将显示给用户,因此我希望它尽可能地匹配用户用其原始语言编写的内容。
修改
好的人,谢谢你否定帖子而不是解决我的问题,耶! :)也许我应该省略用例。但请允许我澄清一下。我需要转换名称才能在内部存储它。 我无法控制此处允许的字母选择。用户可以看到该名称,例如URL。与您在此论坛上的用户名进行规范化相同的方式,如果您点击您的名字,则会在URL中向您显示。这个论坛将“Băşan”等名称转换为“baan”,将名称“Øyvind”转换为“yvind”。我相信它可以做得更好。我正在寻找想法,最好是图书馆功能为我这样做。我知道我做不到,我知道“o”和“ø”不同等,但如果我的名字是“Øyvind”并且我在一个在线论坛上注册,我可能更喜欢我的用户名是“ oyvind“而不是”yvind“。希望这有任何意义!谢谢!
(不,我们不允许用户选择自己的用户名。我真的只是在寻找java.text.Normalizer的替代品。谢谢!)
答案 0 :(得分:2)
假设你已经考虑了你正在做的所有影响,所有它可能出错的方式,当你得到中文象形图和其他没有拉丁字母相同的东西时你会做什么...
我所知道的图书馆没有你想做的。如果你有一个等价列表(如你所说,'æ'到'ae'或其他什么),你可以将它们存储在一个文件中(或者,如果你这么做,在内存中的排序数组中,出于性能原因)然后进行查找并按字符替换。如果你在内存中有空间来存储(unicode字符的数量)作为一个char数组,那么能够运行每个字符的unicode值并进行直接查找将是最有效的。
即,/ u1234 => lookupArray [1234] => 'Q'
或其他什么。
所以你将有一个看起来像这样的循环:
StringBuffer buf = new StringBuffer();
for (int i = 0; i < string.length(); i++) {
buf.append(lookupArray[Character.unicodeValue(string.charAt(i))]);
}
我是从头开始编写的,所以可能会有一些不好的方法调用。
你可能需要做一些事情来处理分解的字符,可能还有一个先行缓冲区。
祝你好运 - 我确信这充满了陷阱。