gpt4 book ai didi

java - 在 Android 中区分 CJK 语言(中文、日文、韩文)

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:24:51 34 4
gpt4 key购买 nike

我希望能够识别中文、日文和韩文的书面字符,既可以作为一般语言,也可以作为分割语言。这些是原因:

  • 将 CJK 识别为一个通用组:我正在制作一个垂直脚本蒙古语 TextView。为此,我需要将文本行旋转 90 度,因为字形是水平存储在字体中的。但是,对于 CJK 语言,我需要将它们再次旋转回来,以便它们以正确的方向书写,但只是彼此堆叠在一起。
  • 将 CJK 区分为特定语言:我也在制作蒙古语词典,当用户输入 CJK 字符进行查找时,我想自动识别该语言。因为汉字也被日本人和韩国人使用,我猜我不能完全做到这一点,但我想在编码允许的最大程度上做到这一点。

在语言方面,我知道的子类别是

为了完整起见,Vietnamese中也使用了汉字(因此 CJK 也称为 CJKV)。对于我目前的目的,我不需要担心它,但它可能是 future 的考虑因素。我也忽略了像中文这样的罗马化脚本 pinyin或日语 romaji .它们在 TextView 中的处理方式与英语和蒙古语相同(即,与该行的其余部分一起旋转 90 度)。 Bopomofo在台湾使用也可能是 future 的考虑,但我暂时不考虑。另见 herehere语言示例。

我见过许多相关问题,这些问题通常涉及 Java 或 Android 中的一种特定语言,但没有包含规范答案的总体问题。其他问题对于 Unicode 更为普遍,但没有说明如何在 Java 和 Android 中进行。以下是一些具体的内容。

所以我的问题是,使用 Unicode 代码点可以在多大程度上区分 CJK 语言以及如何在 Android 中测试它们?我在 Java 和 Android 中看到了一些较新的测试,虽然了解这些测试很有用,但我还需要支持较旧的 Android 设备。

最佳答案

统一码

Unicode中的CJK(和CJKV)是指Han Ideographs,即用于中文、日文、韩文和越南文的汉字(汉字)。对于 Unicode 脚本命名,它指的是日语片假名和平假名或韩语韩文等注音文字。据说汉 Intent 是统一的。他们的意思是每个表意文字只有一个 Unicode 代码点,无论它用于哪种语言。

这意味着 Unicode(以及相反的 Android/Java)无法提供仅基于单个表意文字来确定语言的方法。即使是中文简体/繁体字符也不容易与编码区分开来。这与无法知道字符“a”属于英语、法语还是西类牙语是一样的。需要更多上下文才能确定这一点。

但是,您可以使用 Unicode 编码来确定日文平假名/片假名和韩文韩文。而这些字符的存在将很好地表明附近的汉表意文字属于同一种语言。

安卓

你可以在一些索引处找到代码点

int codepoint = Character.codePointAt(myString, offset)

如果你想 iterate through the codepoints in a string :

final int length = myString.length();
for (int offset = 0; offset < length; ) {
final int codepoint = Character.codePointAt(myString, offset);

// use codepoint here

offset += Character.charCount(codepoint);
}

一旦你有了代码点,你就可以查找它在哪个代码块中了

Character.UnicodeBlock block = Character.UnicodeBlock.of(codepoint);

然后您可以使用代码块来测试表意文字或语言。

中日韩文

扫描Unicode代码块,我认为这些涵盖了所有CJK表意文字。如果我遗漏了任何内容,请随时编辑我的答案或发表评论。

private boolean isCJK(int codepoint) {
Character.UnicodeBlock block = Character.UnicodeBlock.of(codepoint);
return (
Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS.equals(block)||
Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A.equals(block) ||
Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B.equals(block) ||
Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C.equals(block) || // api 19
Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D.equals(block) || // api 19
Character.UnicodeBlock.CJK_COMPATIBILITY.equals(block) ||
Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS.equals(block) ||
Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS.equals(block) ||
Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT.equals(block) ||
Character.UnicodeBlock.CJK_RADICALS_SUPPLEMENT.equals(block) ||
Character.UnicodeBlock.CJK_STROKES.equals(block) || // api 19
Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION.equals(block) ||
Character.UnicodeBlock.ENCLOSED_CJK_LETTERS_AND_MONTHS.equals(block) ||
Character.UnicodeBlock.ENCLOSED_IDEOGRAPHIC_SUPPLEMENT.equals(block) || // api 19
Character.UnicodeBlock.KANGXI_RADICALS.equals(block) ||
Character.UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS.equals(block));
}

带注释的(向右滚动)仅在 API 级别 19 中可用。但是,如果您需要支持早期版本,则可以安全地删除这些,因为它们很少使用。此外,Unicode 定义了 CJK 扩展 E,但在撰写本文时,Android/Java 不支持它。如果您确实需要包含所有内容,那么您可以直接将代码点与 Unicode block 范围进行比较。 This site is a convenient place to browse them.您还可以在 Unicode site 查看它们.

如果你不需要支持 API 19 以下,那么 isIdeographic 使测试变得非常简单(虽然我不知道它是否返回与上面的方法完全相同的匹配)。

private boolean isCJK(int codepoint) {
return Character.isIdeographic(codepoint);
}

或者 API 24+ 的这个:

private boolean isCJK(int codepoint) {
return (Character.UnicodeScript.of(codepoint) == Character.UnicodeScript.HAN);
}

日语

对于测试平假名或片假名,这应该可以正常工作:

private boolean isJapaneseKana(int codepoint) {
Character.UnicodeBlock block = Character.UnicodeBlock.of(codepoint);
return (
Character.UnicodeBlock.HIRAGANA.equals(block) ||
Character.UnicodeBlock.KATAKANA.equals(block) ||
Character.UnicodeBlock.KATAKANA_PHONETIC_EXTENSIONS.equals(block));
}

如果您支持 API 24+,则执行此操作:

(这需要更多测试。请参阅下面的评论。)

private boolean isJapaneseKana(int codepoint) {
return (Character.UnicodeScript.of(codepoint) == Character.UnicodeScript.HIRAGANA ||
Character.UnicodeScript.of(codepoint) == Character.UnicodeScript.KATAKANA);
}

韩语

要在较低的 API 上测试韩文,您可以使用

private boolean isKoreanHangul(int codepoint) {
Character.UnicodeBlock block = Character.UnicodeBlock.of(codepoint);
return (Character.UnicodeBlock.HANGUL_JAMO.equals(block) ||
Character.UnicodeBlock.HANGUL_JAMO_EXTENDED_A.equals(block) || // api 19
Character.UnicodeBlock.HANGUL_JAMO_EXTENDED_B.equals(block) || // api 19
Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO.equals(block) ||
Character.UnicodeBlock.HANGUL_SYLLABLES.equals(block));
}

如有必要,删除标记为 API 19 的行。

或者对于 API 24+:

private boolean isKoreanHangul(int codepoint) {
return (Character.UnicodeScript.of(codepoint) == Character.UnicodeScript.HANGUL);
}

进一步研究

关于java - 在 Android 中区分 CJK 语言(中文、日文、韩文),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41982073/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com