Как классифицировать японские символы как кандзи или кана? - PullRequest
15 голосов
/ 30 сентября 2010

Учитывая текст ниже, как я могу классифицировать каждый символ как Кана или Кандзи ?

誰 か 確認 上 記 こ れ ら の フ

Чтобы получить что-то подобное

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

(Извините, если я сделал это неправильно.)

Ответы [ 5 ]

33 голосов
/ 30 сентября 2010

Эта функциональность встроена в класс 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

, где - полныйширина символаТак что это в той же категории, что и полуширина катакана выше.Обратите внимание, что полная ширина отличается от обычной (полуширина) A:

Character.UnicodeBlock.of('A') == BASIC_LATIN
14 голосов
/ 30 сентября 2010

Используйте таблицу типа this , чтобы определить, какие значения Unicode используются для катаканы и кандзи, затем вы можете просто привести символ к int и проверить, где он находится, что-то вроде

int val = (int)て;
if (val >= 0x3040 && val <= 0x309f)
  return KATAKANA
..
6 голосов
/ 30 сентября 2010

Похоже, было бы интересно использовать класс 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));
  }
}

Выполнение этой команды печатает ожидаемое:

誰 か 確認 上 記 こ れ ら の フ

Хирагана: 101 こ れ ら の

Катакана: 101

Кана: か こ れ ら の フ

Кандзи: 101 確認 上 記

Это дает вам много возможностей для работы с японским текстом, определяя правила для определения того, находится ли персонаж в одной из этих групп в объекте, который может не только сам выполнять много полезных дел, но также может использоваться с другими API, такими как Splitter класс Guava.

Edit:

Основываясь на ответе 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);

Я думаю, что это может быть немного медленнее, чем в другой версии.

4 голосов
/ 30 сентября 2010

Вам необходимо получить ссылку, в которой указаны отдельные диапазоны символов кана и кандзи. Из того, что я видел, алфавиты и эквиваленты обычно получают блок символов.

0 голосов
/ 30 июня 2011

Я знаю, что вы не просили 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
...