2011-11-07 282 views
4

如何规范化/不规范Java中的文本?我目前正在使用java.text.Normalizer:Java中规范化/非规范化文本

Normalizer.normalize(str, Normalizer.Form.NFD) 
    .replaceAll("\\p{InCombiningDiacriticalMarks}+", "") 

但它是远非完美。例如,挪威人的字符æ和ø不变。有谁知道一个替代方案?我正在寻找能够将各种语言的字符转换为a-z范围的东西。我意识到有不同的方法可以做到这一点(例如应该被编码为'a','e',甚至'ae'?),并且我愿意为任何解决方案开放。我宁愿不自己写点东西,因为我认为我不太可能为所有语言都做好这件事。性能并不重要。

用例:我想将用户输入的名称转换为普通的a-z范围名称。转换后的名称将显示给用户,所以我希望它尽可能匹配用户用其原始语言编写的内容。

编辑:

好的人,感谢negging后并没有解决我的问题,耶! :)也许我应该排除用例。但请允许我澄清。我需要将名称转换为内部存储。 我无法控制这里允许选择的字母。该名称将在例如URL中对用户可见。如果你点击你的名字,你在这个论坛上的用户名被标准化并显示在你的URL中。此论坛将“Băşan”之类的名称转换为“baan”,并将“Øyvind”之类的名称转换为“yvind”。我相信它可以做得更好。我正在寻找想法,最好是一个库函数来为我做这件事。我知道我不能说清楚,我知道“o”和“ø”是不同的,但是如果我的名字是“Øyvind”,并且我在网上论坛上注册,我可能更喜欢我的用户名是“ oyvind“而不是”yvind“。希望这是有道理的!谢谢!

(不,我们不会让用户挑选自己的用户名。我真的只是寻找一个替代java.text.Normalizer。谢谢!)

+3

许多语言(如您的示例中的挪威语)具有与拉丁a-z范围* *不同的字符。 ø不仅仅是一个斜杠(并且斜杠不是*可选)。为什么不向用户显示他们的专有名称,而不是损坏的版本? –

+3

您无法将所有名称转换为a-z。 Annabel-Sue不能转换,因为它有一个连字符。其他字母如西里尔文,希腊文,Perso-Arabic的名称不能简单地转换为罗马字母。我不知道你为什么要这样做,但是在人名上强加结构很少是正确的做事方式。 –

+0

谢谢,但我不希望这是讨论是否应该正常化文本或不。我尽可能地存储和显示用户的原始名称,但在某些情况下仍会显示标准化版本。哎呀,这个网站也是这样。如果您的计算器名称是“Băşan”,那么您的用户名将是“baan”。此名称通过您的个人资料显示给您和其他人。我不熟悉罗马尼亚语,但会猜测“basan”会是更好的音译吗?连字符,撇号等可能不得不去。我正在寻找一个工具来为我做这件事。 – John

回答

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))]); 
} 

我写了从无到有,所以有可能是一些不良的方法调用或东西。

你必须做一些事情来处理分解的字符,可能带有一个超前缓冲区。

祝你好运 - 我敢肯定,这充满了陷阱。

+0

您也可以使用地图并执行string.replace(...)。就像所有人一样,我对这种替代品有点担心,因为总是存在一个未知的元素(角色是你没有预见到的!)。 – aishwarya

+0

map/string.replace也是我的第一件事,但出于性能原因,我认为这会慢很多。 String.replace()将会是字符串大小的O(N),并且地图查找是大O在那里的任何东西(天真地说,我认为它是O(M),大小是元素的大小地图)。 做数组查找是O(1),并建立字符串缓冲区O(1)摊销,所以它会* *更快,通过长字符串和这将需要处理每个unicode字符不可能大的映射。 – Kane

+0

感谢凯恩专注于这个问题!是的,我认为你的方法,我认为这是做事最有效的方法。正如我在OP中注意到的,以及其他人也注意到的那样,我不太喜欢使用这种方法,因为我肯定会错过某些我不太熟悉的语言错误的东西或音译错误。如果我没有找到更好的办法,那就是我最终可能做的事情。 – John