2017-02-01 26 views
4

中国語、日本語、韓国語の文字を、一般的なグループと細分化された言語の両方で認識できるようにします。これらは、理由のある:AndroidでCJK言語(中国語、日本語、韓国語)を区別する

  • は、一般的なグループとしてCJKを認識する:私はTextViewモンゴル縦スクリプトを作っています。そのためには、グリフがフォントに水平に格納されているので、テキストの行を90度回転させる必要があります。しかし、CJK言語では、正しい向きで書かれていて、行の上に重ねて積み重ねられるように、それらを再び回転させる必要があります。
  • CJKを特定の言語に区別する:また、モンゴル語の​​辞書を作成しています。ユーザーがCJK文字を入力して検索すると、その言語を自動的に認識したいと思います。漢字は日本人や韓国人にも使われているので、私はこれを完全に達成することはできないだろうと思っていますが、コーディングが許す範囲でできるようにしたいと思います。言語的な面では

、私が知っサブカテゴリが

、漢字も(そうCJKもCJKVと呼ばれている)Vietnameseで使用されています。私の現在の目的のために、私はそれについて心配する必要はありませんが、それは将来の考慮事項になる可能性があります。私は中国語pinyinや日本語romajiのようなローマ字のスクリプトも無視しています。 TextViewでは英語とモンゴル語と同じように扱われます(つまり、残りの行と90度回転しています)。台湾で使用されているBopomofoも将来の検討事項になる可能性がありますが、今は無視します。言語の例については、hereおよびhereも参照してください。

JavaやAndroidで特定の言語を扱うのが普通ですが、標準的な答えでは重要な質問はありません。他の質問は、Unicodeの方が一般的ですが、JavaとAndroidでどうやって行うのかは教えてください。ここにいくつかのものがあります。

だから私の質問は、私はUnicodeのコードポイントを使用して、CJK言語を区別することができ、どのように私はAndroidの中で彼らのためにテストすることができますどのくらい、ありますか?私はJavaとAndroidでいくつかの新しいテストを見てきましたが、これらはわかりやすいですが、古いAndroidデバイスもサポートする必要があります。

答えて

11

ユニコードでのUnicode

CJK(およびCJKVは)それは、中国語、日本語、韓国語、ベトナム語で使用される漢字(汉字)であり、漢漢字を指します。 Unicodeスクリプトの命名については、ではなく、は、日本語カタカナとひらがなまたは韓国語ハングルのような表音文字を指します。漢字表記は統一されていると言われています。これにより、各表意文字のUnicodeコードポイントが1つだけであることを意味します。

これは、Unicode(逆にAndroid/Java)では、単一の文字列に基づいて言語を判断する方法がないことを意味します。単独で表意文字。中国語の簡体字/繁体字の文字でも、エンコードとは容易に区別できません。これは、文字「a」が英語、フランス語、またはスペイン語に属するかどうかを知ることができないという考えと同じです。それを決定するためには、より多くのコンテキストが必要です。

ただし、Unicodeエンコードを使用して、日本語のひらがな/カタカナと韓国語のハングルを判別できます。そのような文字の存在は、近くの漢字表記が同じ言語に属していることを示す良い指標となります。

アンドロイド

あなたは

int codepoint = Character.codePointAt(myString, offset) 

でいくつかの指標でコードポイントを見つけることができますし、iterate through the codepoints in a stringしたい場合:あなたはコードポイントを持っていたら

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

そしてコードブロックを使用して、表意文字や言語をテストすることができます。

CJK

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 Extension Eを定義していますが、この時点ではAndroid/Javaではサポートされていません。すべてを含める必要がある場合は、コードポイントをUnicodeブロック範囲と直接比較できます。 This site is a convenient place to browse them.Unicode siteでもご覧になれます。

以下のAPI19をサポートする必要がない場合、isIdeographicはテストを非常に簡単にします(ただし、上記のメソッドとまったく同じ一致が返されるかどうかはわかりませんが)。

private boolean isCJK(int codepoint) { 
    return Character.isIdeographic(codepoint); 
} 

または24+ APIについては、この1:

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+をサポートしています:

(これはより多くのテストが必要です。必要に応じて、下記のコメントを参照してください。)下のAPIにハングルをテストするために

韓国

private boolean isJapaneseKana(int codepoint) { 
    return (Character.UnicodeScript.of(codepoint) == Character.UnicodeScript.HIRAGANA || 
      Character.UnicodeScript.of(codepoint) == Character.UnicodeScript.KATAKANA); 
} 

はあなたが

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

は、さらなる研究Character.UnicodeScriptがをどのように機能するかを示して

+0

こんにちは、あなたのAPIのように思える24+ isJapanese方法はこれについてコメントを残してくれてありがとう、katanka – tObi

+0

@tObiとしてー認識しません。以前のAPI 24をサポートする必要があるので、私は自分のプロダクションプロジェクトでAPI 24+のコードを使用していませんでした。あなたが何が間違っているか、それを解決する方法を発見したら、別のコメントを残してください。 – Suragch

+0

@tObi、テスト目的で、認識されない特定のカタカナ文字を教えてもらえますか? – Suragch

関連する問題