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

鉴于下面的文字,我如何将每个角色分类为假名或汉字 ?

谁か确认上记これらのフ

得到这样的东西

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

(对不起,如果我做错了。)

此function内置于Character.UnicodeBlock类中。 与日语相关的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 

其中是全角字符。 因此,这与上面的半宽Katakana 属于同一类别。 请注意,全宽与正常(半宽) A

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

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

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

对于Guava的CharMatcher课程来说,这似乎是一个有趣的用途。 使用杰克答案中链接的表格,我创建了这个:

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

运行此打印预期:

谁か确认上记これらのフ

平假名:かこれらの

片假名:フ

假名:かこれらのフ

汉字:谁确认上记

通过定义用于确定某个字符是否属于某个对象的其中一个组中的规则,这可以为您提供处理日语文本的强大function,该对象本身不仅可以执行许多有用的操作,还可以与其他API一起使用比如Guava的Splitter类。

编辑:

基于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); 

我认为这可能比其他版本慢一点。

您需要获得一个引用,该引用为假名和汉字字符提供单独的范围。 从我所看到的,字母和等价物通常会得到一个字符块。

我知道你没有要求VBA,但对于那些想知道的人来说,这里有VBA风味:

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

 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