WVr*_*ock 9 java unicode normalization unicode-normalization
我想将英语(i)的"I"的小写字母与土耳其语(i)的"İ"的小写字母相匹配.它们是相同的字形,但它们不匹配.当我做System.out.println("?".toLowerCase());字符i和打印点(此网站不能正确显示)
有没有办法匹配那些?(最好没有硬编码)我想让程序匹配与语言和utf代码无关的相同字形.这可能吗?
我测试了规范化没有成功.
public static void main(String... a) {
String iTurkish = "\u0130";//"?";
String iEnglish = "I";
prin(iTurkish);
prin(iEnglish);
}
private static void prin(String s) {
System.out.print(s);
System.out.print(" - Normalized : " + Normalizer.normalize(s, Normalizer.Form.NFD));
System.out.print(" - lower case: " + s.toLowerCase());
System.out.print(" - Lower case Normalized : " + Normalizer.normalize(s.toLowerCase(), Normalizer.Form.NFD));
System.out.println();
}
Run Code Online (Sandbox Code Playgroud)
结果未在网站中正确显示,但第一行(iTurkish)仍然具有? 接近小写的i.
目的和问题
这将是一个多语言词典.我希望程序能够识别"İFEL"以"if"开头.为了确保它们不区分大小写,我首先将两个文本转换为小写.İFEL成为i(点)fel并且"if"未被识别为其中的一部分
dim*_*414 10
如果您打印出您所看到的字符的十六进制值,则区别很明显:
? 0x130 - Normalized : I? 0x49 0x307 - Lower case: i? 0x69 0x307 - Lower case Normalized : i? 0x69 0x307
I 0x49 - Normalized : I 0x49 - Lower case: i 0x69 - Lower case Normalized : i 0x69
Run Code Online (Sandbox Code Playgroud)
归一化土耳其语?不会给你一个英语I,而是给你一个英语,I后面跟一个变音符号,0x307.这是正确的,并且可以通过规范化过程来预期.规范化不是"转换为ASCII"操作.作为Normalizer提及的文档,它遵循的过程是一个非常严格定义的标准,Unicode标准附件#15 - Unicode规范化表单.
在标准化之前或之后,有许多方法可以去除变音符号.您需要的将取决于您的用例的具体情况,但对于您的用例,我建议使用Guava的CharMatcher类在规范化后删除非ASCII字符,例如:
String asciiString = CharMatcher.ascii().retainFrom(normalizedString);
Run Code Online (Sandbox Code Playgroud)
这个答案更深入地讲述了什么\p{InCombiningDiacriticalMarks},以及为什么它不理想.我的CharMatcher解决方案也不理想(链接的答案提供了更强大的解决方案),但是为了快速修复,您可能会发现仅保留"足够好"的ASCII字符.这比Pattern基于方法更接近"正确"和更快.
| 归档时间: |
|
| 查看次数: |
831 次 |
| 最近记录: |