2009-11-04 3 views
7

私はJavaアプリケーションを作成しています。しかし、この点に固執しています。Javaで漢字のみを分割するには

查詢促進民間參與公共建設法(210BOT法). 

は、私は上記の「BOT」として、ラテン語や数字を除いて、これらの中国の文字を分割したい:

は基本的に私はまた、いくつかの可能なラテン文字や数字と漢字の文字列を持っている、と言うことができます。

[ 查, 詢, 促, 進, 民, 間, 參, 與, 公, 共, 建, 設, 法, (, 210, BOT, 法, ), ., ]

どのように私は(Java用)この問題を解決することができます:だから、最後に私は、リストのこの種を持っているのだろうか?

答えて

10

漢字特定のUnicode内にある範囲:

  • 2F00-2FDF:康
  • 4E00-9FAF:CJK
  • 3400-4DBF:あなたは基本的にCJK拡張

だから、すべてをキャラクターのコードポイントが既知の範囲内にあるかどうかを確認する必要があります。 (:Character#isDigit()ヒント):

Set<UnicodeBlock> chineseUnicodeBlocks = new HashSet<UnicodeBlock>() {{ 
    add(UnicodeBlock.CJK_COMPATIBILITY); 
    add(UnicodeBlock.CJK_COMPATIBILITY_FORMS); 
    add(UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS); 
    add(UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT); 
    add(UnicodeBlock.CJK_RADICALS_SUPPLEMENT); 
    add(UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION); 
    add(UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS); 
    add(UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A); 
    add(UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B); 
    add(UnicodeBlock.KANGXI_RADICALS); 
    add(UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS); 
}}; 

String mixedChinese = "查詢促進民間參與公共建設法(210BOT法)"; 

for (char c : mixedChinese.toCharArray()) { 
    if (chineseUnicodeBlocks.contains(UnicodeBlock.of(c))) { 
     System.out.println(c + " is chinese"); 
    } else { 
     System.out.println(c + " is not chinese"); 
    } 
} 

幸運をこの例では、あなただけの十分明白であるべき、ラテン文字から数字を分離するためにそれを拡張する必要があり、stackbasedパーサ/スプリッタを書くために良い出発点です。

+0

、私は正規表現の文字クラスを信じています。上記のユニコード範囲にまたがって動作するでしょう。 –

+0

数字/文字/ハイフン/ whateverlatinのグループを傍受したい場合は、実際にはありません。スタックベースのパーサは、この種のジョブに適したツールです。 – BalusC

+0

これは日本語と韓国語でも機能しますか? –

1

ここに私が取るアプローチがあります。

Character.codePointAt(char [] charArray、int index)を使用すると、char配列のcharのUnicode値を返すことができます。

ラテン語のUnicode文字のマッピングも必要です。

Character.UnicodeBlockのソースを見ると、完全なLATINブロックは[0x0000,0x0249]の間隔です。したがって、基本的には、Unicodeコードポイントがその間隔のどこかにあるかどうかをチェックします。

Character.Subsetを使用して文字が含まれているかどうかを確認する方法があると思われますが、それについては検討していません。

1

Diclaimer:私は完全なLucene初心者です。

Lucene(執筆時点では3.6.0)の最新バージョンを使用して、私はあなたが必要とする結果に近づくことができます。

Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36, Collections.emptySet()); 

    List<String> words = new ArrayList<String>(); 
    TokenStream tokenStream = analyzer.tokenStream("content", new StringReader(original)); 
    CharTermAttribute termAttribute = tokenStream.addAttribute(CharTermAttribute.class); 

    try { 
    tokenStream.reset(); // Resets this stream to the beginning. (Required) 
    while (tokenStream.incrementToken()) { 
     words.add(termAttribute.toString()); 
    } 
    tokenStream.end(); // Perform end-of-stream operations, e.g. set the final offset. 
    } 
    finally { 
    tokenStream.close(); // Release resources associated with this stream. 
    } 

私が得る結果は次のとおりです。拡張として

[查, 詢, 促, 進, 民, 間, 參, 與, 公, 共, 建, 設, 法, 210bot, 法] 
関連する問題