我希望将英语(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();
}
结果未在网站中正确显示,但第一行(iTurkish)的̇
仍然接近小写i。
目的和问题
这将是一个多语言词典。我希望程序能够识别“İFEL”以“if”开头。为了确保它们不区分大小写,我首先将两个文本转换为小写。 İFEL成为i(点)fel并且“if”未被识别为其中的一部分
答案 0 :(得分:10)
如果您打印出您所看到的字符的十六进制值,则差异很明显:
İ 0x130 - Normalized : İ 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
规范化土耳其语İ
并不会为您提供英语I
,而是会为您提供英语I
,后跟变音符号0x307
。这是正确的,并且可以通过规范化过程来预期。规范化不是"转换为ASCII"操作。正如Normalizer
提到的文档一样,它所遵循的流程是一个非常严格定义的标准Unicode Standard Annex #15 — Unicode Normalization Forms。
在标准化之前或之后有numerous ways to strip diacritics。您需要的将取决于您的用例的具体情况,但对于您的用例,我建议使用Guava的CharMatcher
类在规范化后删除非ASCII字符,例如:< / p>
String asciiString = CharMatcher.ascii().retainFrom(normalizedString);
This answer更深入地了解了\p{InCombiningDiacriticalMarks}
的作用,以及为什么它不理想。我的CharMatcher
解决方案也不理想(链接的答案提供了更强大的解决方案),但为了快速解决问题,您可能会发现仅保留ASCII字符&#34;足够好&#34;。这更接近&#34;正确&#34;并且比基于Pattern
的方法更快。
答案 1 :(得分:-1)
您可以使用以下代码:
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);
String nfdNormalizedString = Normalizer.normalize(s, Normalizer.Form.NFD);
Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
System.out.print(" - Normalized : " + pattern.matcher(nfdNormalizedString).replaceAll(""));
System.out.print(" - lower case: " + s.toLowerCase());
System.out.print(" - Lower case Normalized : " + Normalizer.normalize(pattern.matcher(nfdNormalizedString).replaceAll("").toLowerCase(), Normalizer.Form.NFD));
System.out.println();
}