Java 如何将日语字符分类为汉字或假名?

Java 如何将日语字符分类为汉字或假名?,java,unicode,cjk,Java,Unicode,Cjk,鉴于以下文本,我如何将每个字符分类为或 誰か確認上記これらのフ 得到这样的东西 誰 - kanji か - kana 確 - kanji 認 - kanji 上 - kanji 記 - kanji こ - kana れ - kana ら - kana の - kana フ - kana (如果我做得不正确,很抱歉。)您需要获得一个参考,该参考给出假名和汉字的单独范围。据我所见,字母表和等价物通常会得到一个字符块。使用类似表的表格来确定片假名和汉字使用哪些unicode值,然后您可以简单

鉴于以下文本,我如何将每个字符分类为或

誰か確認上記これらのフ

得到这样的东西

誰 - kanji
か - kana
確 - kanji
認 - kanji 
上 - kanji 
記 - kanji 
こ - kana 
れ - kana
ら - kana
の - kana
フ - kana

(如果我做得不正确,很抱歉。)

您需要获得一个参考,该参考给出假名和汉字的单独范围。据我所见,字母表和等价物通常会得到一个字符块。

使用类似表的表格来确定片假名和汉字使用哪些unicode值,然后您可以简单地将字符转换为int并检查它所属的位置,如

int val = (int)て;
if (val >= 0x3040 && val <= 0x309f)
  return KATAKANA
..
intval=(int)て;

如果(val>=0x3040&&val这似乎是对的类的有趣使用。使用Jack答案中链接的表,我创建了以下内容:

public class JapaneseCharMatchers {
  public static final CharMatcher HIRAGANA = 
      CharMatcher.inRange((char) 0x3040, (char) 0x309f);

  public static final CharMatcher KATAKANA = 
      CharMatcher.inRange((char) 0x30a0, (char) 0x30ff);

  public static final CharMatcher KANA = HIRAGANA.or(KATAKANA);

  public static final CharMatcher KANJI = 
      CharMatcher.inRange((char) 0x4e00, (char) 0x9faf);

  public static void main(String[] args) {
    test("誰か確認上記これらのフ");
  }

  private static void test(String string) {
    System.out.println(string);
    System.out.println("Hiragana: " + HIRAGANA.retainFrom(string));
    System.out.println("Katakana: " + KATAKANA.retainFrom(string));
    System.out.println("Kana: " + KANA.retainFrom(string));
    System.out.println("Kanji: " + KANJI.retainFrom(string));
  }
}
运行此命令将打印预期的:

誰か確認上記これらのフ

平假名:かこれらの

片假名:フ

卡纳:かこれらのフ

汉字:誰確認上記

这为您提供了大量处理日文文本的能力,通过定义规则来确定一个字符是否位于对象中的这些组中,该对象本身不仅可以做很多有用的事情,还可以与其他API(如Guava的
拆分器
类)一起使用

编辑:

根据jleedev的回答,您还可以编写如下方法:

public static CharMatcher inUnicodeBlock(final Character.UnicodeBlock block) {
  return new CharMatcher() {
    public boolean matches(char c) {
      return Character.UnicodeBlock.of(c) == block;
    }
  };
}
然后像这样使用它:

CharMatcher HIRAGANA = inUnicodeBlock(Character.UnicodeBlock.HIRAGANA);

我认为这可能比另一个版本慢一点。

此功能内置于类中。一些与日语相关的Unicode块示例:

Character.UnicodeBlock.of('誰') == CJK_UNIFIED_IDEOGRAPHS
Character.UnicodeBlock.of('か') == HIRAGANA
Character.UnicodeBlock.of('フ') == KATAKANA
Character.UnicodeBlock.of('フ') == HALFWIDTH_AND_FULLWIDTH_FORMS
Character.UnicodeBlock.of('!') == HALFWIDTH_AND_FULLWIDTH_FORMS
Character.UnicodeBlock.of('。') == CJK_SYMBOLS_AND_PUNCTUATION
但是,与往常一样,魔鬼在于细节:

Character.UnicodeBlock.of('A') == HALFWIDTH_AND_FULLWIDTH_FORMS
其中
是全宽字符。因此它与半宽片假名
请注意,整个宽度
不同于正常(半宽)
A

Character.UnicodeBlock.of('A') == BASIC_LATIN

我知道你没有要求VBA,但以下是VBA的味道,供那些想知道的人参考:

这里有一个函数可以做到这一点。它会像上面一样将句子分解为一个单元格。您可能需要添加一些错误检查,以了解如何处理换行符或英语字符等。但这应该是一个好的开始

Function KanjiKanaBreakdown(ByVal text As String) As String

Application.ScreenUpdating = False
Dim kanjiCode As Long
Dim result As String
Dim i As Long

For i = 1 To Len(text)
    If Asc(Mid$(text, i, 1)) > -30562 And Asc(Mid$(text, i, 1)) < -950 Then
        result = (result & (Mid$(text, i, 1)) & (" - kanji") & vbLf)
    Else
        result = (result & (Mid$(text, i, 1)) & (" - kana") & vbLf)
    End If
Next

KanjiKanaBreakdown = result
Application.ScreenUpdating = True

End Function
函数KanjiKanaBreakdown(ByVal文本作为字符串)作为字符串 Application.ScreenUpdating=False 模糊的汉字码一样长 将结果变暗为字符串 我想我会坚持多久 对于i=1到Len(文本) 如果Asc(Mid$(文本,i,1))大于-30562,而Asc(Mid$(文本,i,1))小于-950,则 结果=(结果和中间$(文本,i,1))&(“-kanji”)&vbLf) 其他的 result=(result&(Mid$(text,i,1))&(“-kana”)&vbLf) 如果结束 下一个 KanjiKanaBreakdown=结果 Application.ScreenUpdating=True 端函数
你所说的“拆分”到底是什么意思?更新了问题,使目标更加明确。象形文字是古埃及文字的一种形式。它们与现代日本文字形式无关。@alex2k8-我们现在理解你所说的“拆分”的意思。但拆分并不是这个意思。你真正想做的是“分类”日语字符(不是象形文字!!)可以是汉字或假名。(拆分意味着将字符放入不同的堆/集合…@alex2k8:你想区分“表意文字”和“音节”(“音节”的复数形式)。假名是音节:片假名和平假名都是音节。正如Stephen C所说(+1),象形文字在这里没有什么关系;)这真的不难,因为只有大约60个平假名和60个片假名(我以前知道它们;)好吧,在Unicode中,汉字的范围是U+4E00到U+9FBF,片假名的范围是U+30A0到U+30FF,平假名的范围是U+3040到U+309F。根据拆分的实际情况,“拆分”文本应该很容易。这并不像听起来那么容易,因为每个文本都有多个范围。有趣的是,我不知道这一点。但是CJK_UNIFIED_表意文字并不是默认的,我想还需要一个额外的导入语句,除了角色所需要的,我甚至不知道这是一个函数!谢谢是的,如果你只想测试某个特定范围内的成员资格,那么自己测试可能会更快。令人惊讶的是,UnicodeBlock类没有一个方法来测试字符的成员资格,而且似乎唯一的方法是它的静态
of
方法,它在每个块中循环,直到找到一个。请注意,jleedev基本上有相同的方法,但使用的是JVM提供的表。