是否可以将所有类似的Unicode字符分组为合适的ASCII字符

时间:2017-10-30 11:57:53

标签: java string unicode character-encoding grouping

我想拍摄几乎相同的所有符号(来自所有字母)(例如ð,ô,ö,õ,ø)并用最接近的ASCII字符替换它。所以它看起来像:ð,ô,ö,õ,> O操作。 这不必是音译,就像在这个库https://github.com/gcardone/junidecode中一样(我们不应该将符号转换为ASCII(靠近含义,例如Ĉ - > s),但我们应该找到与Unicode组密切相关的ASCII符号(例如Ĉ - C))。

2 个答案:

答案 0 :(得分:1)

我没有任何解决此问题的简单方法,因为您要分组的符号实际上不是一个组。符号Ò,Ó,Õ,Ö,Ø和Ô在形状上都是“类O”,并且具有相似的代码点(0xD2-0xD8)。在某些语言中,他们甚至可能有一些相似的发音,但不能保证。一个典型的例子是字母'eth,'ð,它看起来有点像“o”,但在使用它的任何语言(我所知道的)中都没有以类似的方式发音。你已经认识到法语中的“ç”更容易将发音与“s”相关联,而不是形状类似于“c”。

我认为如果你想承担这项任务,你将不得不通过个案代码点转换来做(唉!)但是,认为更难的问题根本不在于编程 - 它会鉴于符号形状和语言角色之间几乎没有联系,找到对读者来说实际上有意义的映射。这种原型错误是将西班牙语“año”(年)称为“ano”(意思是“肛门”)。你真的不想犯这种错误。

答案 1 :(得分:1)

您可以删除组合字符,但并非所有示例都使用它们。例如,ð(eth)本身就是一个字母,而不是带有斜杠的“d”。与波兰语“dark l”相同,ł。

import java.text.Normalizer;

public class RemoveMarks {

  public static void main(String... argv) {
    String src = "ðôöõøĈł";
    String dst = Normalizer.normalize(src, Normalizer.Form.NFKD);
    System.out.println(dst.replaceAll("\\p{Mn}+", ""));
  }

}

这应该打印“ðoooøCł”。你可以看到真正的字母“o”已经删除了它们的组合字符,就像“C”一样。

这提示了一个问题:为什么你想要这样做?你为什么要以一种没有正确意义的方式破坏信息呢?

如果您尝试匹配或搜索或索引文本,则应使用正确配置的Collator作为所需的区域设置。这将自动忽略该区域设置中的用户不关心的差异。例如,在美式英语中,“Naïve”与“naive”相同,而“résumé”只是拼写“RESUME”的闷热方式。整理者可以照顾这些变化。

Collator collator = Collator.getInstance(Locale.US);
collator.setStrength(Collator.PRIMARY);
collator.setDecomposition(Collator.CANONICAL_DECOMPOSITION);
Map<CollationKey, String> map = new HashMap<>();
map.put(collator.getCollationKey("resume"), "resume");
map.put(collator.getCollationKey("naive"), "naive");
System.out.println(map.get(collator.getCollationKey("RéSuMé"))); // resume
System.out.println(map.get(collator.getCollationKey("NAÏVE")));  // naive