当前位置: 首页 > 面试题库 >

在Android中区分CJK语言(中文,日文,韩文)

隗驰
2023-03-14
问题内容

我希望能够将中文,日文和韩文书写的字符识别为一般组和细分语言。原因如下:

  • 将CJK视为一般团体: 我正在制作一个垂直脚本蒙古语TextView。为此,我需要将文本行旋转90度,因为字形是水平存储在字体中的。但是,对于CJK语言,我需要再次将它们旋转回去,以使它们以正确的方向书写,而只是沿线叠放在一起。
  • 将CJK区分为特定的语言: 我也在制作蒙古文字典,当用户输入CJK字符进行查找时,我想自动识别该语言。因为日文和韩文也使用汉字,所以我想我无法完全完成此操作,但我想在编码允许的最大范围内做到这一点。

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

  • 繁体字
  • 中文简体字
  • 日语汉字(汉字)
  • 日语平假名(本机字母)
  • 日语片假名(写外语的字母)
  • 韩文(注音)
  • 韩文汉字(汉字)

为了完整起见,越南语中也使用了汉字(因此CJK也称为CJKV)。就我当前的目的而言,我不必担心,但这可能是将来的考虑。我也忽略了罗马脚本,像中国的拼音或日语罗马字。在TextView中,它们的处理方式与英语和蒙古语相同(即,与行的其余部分旋转90度)。在台湾使用的Bopomofo也可能是未来的考虑因素,但我暂时将其忽略。有关语言示例,请参见此处和此处。

我已经看到了许多相关的问题,这些问题通常涉及Java或Android中的一种特定语言,但是没有包含规范答案的总体问题。对于Unicode,其他问题更为笼统,但并没有说明如何在Java和Android中实现。

所以我的问题是,我可以使用Unicode代码点区分CJK语言多少,如何在Android中对其进行测试?我已经看过Java和Android上的一些较新测试,虽然这些测试很有用,但我还需要支持较旧的Android设备。


问题答案:

Unicode中的CJK(和CJKV)是指汉字表意文字,即在中文,日文,韩文和越南文中使用的汉字(汉字)。对于Unicode的脚本命名,但它 不是
指像日本平假名和片假名或韩文拼音编写的脚本。据说汉族思想图是统一的。意思是说,无论使用哪种表意符号,每个表意文字都只有一个Unicode代码点。

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

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

安卓系统

您可以在某些索引处找到代码点

int codepoint = Character.codePointAt(myString, offset)

如果您想遍历字符串中的代码点,请执行以下操作:

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块范围进行比较。该站点是浏览它们的便捷位置。您也可以在Unicode站点上看到它们。

如果您不需要在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上测试Hangul,可以使用

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

进一步研究

  • Unicode东亚文字
  • Unicode CJK常见问题解答
  • Unicode韩文常见问题解答
  • 一些源代码显示如何Character.UnicodeScript工作
  • 中日韩统一表意文字


 类似资料:
  • Tea 语言是一个和 运行效率接近 C++、开发效率超越 Java 的编程语言。 编译为原生机器码(汇编),兼容主要操作系统和平台。 现代化语言,支持 GC、面向对象、函数式编程、类型推导等流行语言特性。 C 风格,Java 用户可以很快上手。更实用,更适合敏捷开发。 国产。全中文支持。

  • 我有一个中文/韩文字符的超文本标记语言字符串。我想使用iText将超文本标记语言转换为PDF。我读到我们需要将FONT嵌入到PDF中,以使Unicode字符显示在PDF上。 当我尝试嵌入wts11时。ttf(带有编码标识_H)或STSong Light(带有编码Unigb-UCS2-H),我只能看到汉字,但看不到韩文字符。我试着用arialuni。ttf(带有编码标识),但仍然只能看到汉字,不能看

  • 中文版 Apple 官方 Swift 教程《The Swift Programming Language》 目录: 欢迎使用 Swift 关于 Swift(完成 By numbbbbb) Swift 初见(完成 By numbbbbb) Swift 教程 基础部分(完成 By numbbbbb, lyuka, JaySurplus) 基本操作符(完成 By @xielingwang) 字符串和字符

  • R 是用于统计分析,图形表示和报告的编程语言和软件环境。 R 由新西兰奥克兰大学的 Ross Ihaka 和 Robert Gentleman 创建,目前由 R Development Core Team 开发。

  • 这个页面展示如何使用 Dart 的各个主要特性,从变量、运算符到类和库,并且假定你已经会使用其他编程语言编写代码。 要详细了解 Dart 核心库相关内容,请查阅 Dart 库教程。当你想对一个语言特性深入了解时,无论何时都可以查阅 Dart 语言规范。

  • Go 语言是一种编程语言,最初由 Robert Griesemer,Rob Pike 和 Ken Thompson 于 2007 年在 Google 开发。 它是一种静态类型语言,其语法类似于 C 语言。