Подтвердить что ты не робот

Как классифицировать японские символы как кандзи или кану?

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

誰 か 確認 上 記 こ れ ら の フ

Чтобы получить что-то вроде этого

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

Ответ 3

Кажется, что это было бы интересным для 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));
  }
}

Запуск этого режима отображает ожидаемое:

誰 か 確認 上 記 こ れ ら の フ

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

Катакана: フ

Кана: か こ れ ら の フ

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

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

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

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

Ответ 5

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