2013-05-19 8 views
5

文字列から単語数を取得したい。それはそれと同じくらい簡単です。キャッチは、文字列が予測不可能な言語である可能性があることです。(任意の言語の)Unicodeの文字列から単語数を取得する

だから、私は、次のサンプル出力で署名int getWordCount(String)の機能を必要とする -

getWordCount("供应商代发发货") => 7 
getWordCount("This is a sentence") => 4 

続行する方法上の任意の助けをいただければ幸いです:)のために

+0

にある単語間の区切り文字はありますか? –

+0

いいえ、セパレータはありません。私は正確な文字列をコピーしました。 – jaibatrik

+0

その場合、文字列にユニコードのルーンが使用されている言語を見つけようとします。その情報を使用して、文字列の解析方法を決定します。 –

答えて

5

些細なまたは複雑である "単語" のコンセプト。

Wordのトークン化:ここでApache Stanbolツールキットである単一の単語の検出は、テキストを処理するために Stanbolエンハンサーにより必要とされます。これはほとんどの 言語では簡単ですが、一部の東部言語ではかなり複雑な作業です。中国語、日本語、韓国語、 それ以外の場合は、 は空白を使って単語をトークン化します。

語の概念は言語的ではなく、構文であれば、あなたが使用する必要がありますのでNLP toolkit

マイ好適JavaソリューションをApache's Open NLP

NOTEです:私はあなたの例をトークン化するhttp://www.mdbg.net/chindict/chindict.php?page=worddict を使用している 。それは、7つではなく4つの言葉があることを意味する。私はカットして(むしろ断片化)貼り付けています:

オリジナルテキスト簡体 ピンイン 英語の定義は、辞書の伝統的な HSK 供应商 供应商 功英シャン

サプライヤーに新しい単語を追加します。

供應商 代
代 DAI

は、他人のために行動する/置換する/交換する/生成/王朝/年齢/期間/(historical)の時代/(地質学)EON

送信する
FA

发发/ FA

发銃声(ラウンド)用/クラシファイア

發 を開発するために/ HSK 4

を発行する/(自分の気持ちを)表示します

hair /台湾【FA3]

髮发货
发货をFAフオ

これらの最初の3つの文字は、単一を形成するように見える商品

發貨

を送信する/ディスパッチしますワード。

+0

ご協力ありがとうございます。あなたのアプローチは非常に論理的だと思います。私はこれをどのように動かすことができるかを見るためにいくつかのツールキットを見つけようとします。 – jaibatrik

+0

良いあなたは名詞、動詞などを検出するPartOfSpeech Taggerから始めたいと思うかもしれません。そして、あなたの問題を探るのに役立つオンラインサービスはほぼ確実です。そしてあなたの全体的な問題は、おそらく単に単語を見つけることよりも複雑です。 –

+0

これは簡単なツールキット/サービスですか?良い単語トークナイザーかもしれない? – jaibatrik

1

英語版

をあなたはかなり単純なRegexで行うことができる英語版です。私はいくつかのカスタムセパレータを逃したが、していることがあります。

public static int getWordCount(String str) { 
    return str.split("[\\s,;-]+").length; 
} 

正規表現の説明:

[ 
\\s Any whitespace character or 
, A comma 
; or a semi-colon 
] 
+ Followed by any patterns in the group any number of times 

中国語版

の場合:グループ[]で任意のを見つけた場合

スプリット中国語版、あなたはセパレータrsはあります。中国の区切り文字のUnicode charコードを取得して上記の正規表現に追加すると、望ましい結果が得られます。

テスト

System.out.println(getWordCount("This is a sentence"));// 4 
System.out.println(getWordCount("This is a sentence")); // 4 
System.out.println(getWordCount("This is a  ,,sentence")); // 4 
+0

あなたの提案に感謝します。試してみる。 – jaibatrik

2

我々はすべての言語が1つ(またはそれ以上に)単語の区切りを持っており、あなたがそれらの区切りのための正規表現を構築することができますと仮定した場合、問題は次のように解決することができます:

public String separatorForLanguage(char unicodeChar){ 
     // Find out in which language unicodeChar falls 
     return ""; // return regex of separator of that language 
    } 

    public int wordCount(String sentance){ 
     char unicodeChar = sentance.charAt(0); 
     String separator = separatorForLanguage(unicodeChar); 

     int count = sentance.split(separator).length; 
     if (separator.isEmpty()) { 
      count--; 
     } 

     return count; 
    } 
+0

答えをありがとう。実際には、中国語/日本語のテキストにセパレータはなく、それが問題です。 – jaibatrik

+0

@jaibatrik:セパレータは空の文字列です。 – Mohayemin

+0

はい、論理的です。よく準備された擬似コードをありがとう。感謝と賞賛! – jaibatrik

5

標準APIはBreakIteratorを提供この種の境界分析では、Oracle Java 7ロケールのサポートによってサンプル文字列が分割されません。

私がICU4J v51.1 BreakIteratorを使用したとき、それは[供应, 商代, 发, 发, 货]に壊れました。

// import com.ibm.icu.text.BreakIterator; 
String sentence = "\u4f9b\u5e94\u5546\u4ee3\u53d1\u53d1\u8d27"; 
BreakIterator iterator = BreakIterator.getWordInstance(Locale.CHINESE); 
iterator.setText(sentence); 

List<String> words = new ArrayList<>(); 
int start = iterator.first(); 
int end = iterator.next(); 
while (end != BreakIterator.DONE) { 
    words.add(sentence.substring(start, end)); 
    start = end; 
    end = iterator.next(); 
} 
System.out.println(words); 

注:私は、Googleが "供应商代发发货" 中国だったことを推測するために翻訳を使用。明らかに、私は言語を話さないので、出力の正確さについてコメントすることはできません。ここ

+0

共有いただきありがとうございます。アップ投票も! – jaibatrik

2

は、スニペットは中国語(?)テキスト内のJava

public static int getWordCount(String string) 
{ 
    Pattern pattern = Pattern.compile("[\\w']+|[\\u3400-\\u4DB5\\u4E00-\\u9FCC]"); 
    Matcher matcher = pattern.matcher(string); 
    int count = 0; 
    while(matcher.find()) 
     count++; 
    return count;         
} 

//count is 5 
int wordCount = getWordCount("this is popcorny's 電腦"); 
関連する問題