日本語文字列を文節に分解するのに Language Analysis Manager をつかっていたのですが、これが10.5からdeprecatedになって、また32bitしかサポートしていないので、かわりにCFStringTokenizerを利用することにしました。
文字列をあたえると、その文節のRangeのarrayを返す下記の関数をCFStringTokenizerで作りました。
ところがこれがうまく動作してくれません。たとえば「漢字変換をしています」という文字列をあたえると
漢字/変換/を/し/て/い/ます/
のように訳のわからないtokenを返します。
漢字/変換を/しています/
のように正しく分解してくれません。
どなたか正しく動作させる方法をご存知ないでしょうか?
NSArray *tokenRanges( NSString *theString )
{
CFLocaleRef currentLocale =CFLocaleCopyCurrent();
CFStringTokenizerRef tokenizer;
CFRange range;
NSMutableArray *array;
CFStringTokenizerTokenType tokenType;
range = CFRangeMake(0, [theString length]);
NSLog( @"%@", CFLocaleGetIdentifier(currentLocale));
tokenizer = CFStringTokenizerCreate(NULL, (CFStringRef)theString, range, kCFStringTokenizerUnitWordBoundary, currentLocale);
array = nil;
tokenType = CFStringTokenizerGoToTokenAtIndex(tokenizer, 0);
loop:
if( tokenType != kCFStringTokenizerTokenNone )
{
if(!array )array = [NSMutableArray arrayWithCapacity:16];
range = CFStringTokenizerGetCurrentTokenRange(tokenizer);
NSLog( @"tokenType=%x range = %d-%d %@", tokenType, range.location, range.length, [theString substringWithRange:NSMakeRange(range.location, range.length)]);
[array addObject:[NSValue valueWithRange:NSMakeRange(range.location, range.length)]];
if(range.location + range.length < [theString length])
{
tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer);
goto loop;
}
}
CFRelease(tokenizer);
CFRelease(currentLocale);
NSLog( @"numoftokens %d",[array count] );
return array;
}
-----------------------------------------------------
Satoshi Matsumoto <sat...@mac.com>
816-5 Odake, Odawara, Kanagawa, Japan 256-0802
2011年2月2日13:54 MATSUMOTO Satoshi <sat...@mac.com>:
> 漢字/変換/を/し/て/い/ます/
>
> のように訳のわからないtokenを返します。
え、訳がわかりませんか? それでは日本語の文法というものを意識されてみてはどうでしょう。
Mac OS X の内部で使われているという噂の mecab を使うと
漢字 名詞,一般,*,*,*,*,漢字,カンジ,カンジ
変換 名詞,サ変接続,*,*,*,*,変換,ヘンカン,ヘンカン
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
し 動詞,自立,*,*,サ変・スル,連用形,する,シ,シ
て 助詞,接続助詞,*,*,*,*,て,テ,テ
い 動詞,非自立,*,*,一段,連用形,いる,イ,イ
ます 助動詞,*,*,*,特殊・マス,基本形,ます,マス,マス
のようになります。形態素解析というやつですね。Spotlight でも使われているという噂です。
ちなみに上の解析はオリジナルの mecab を使いました。Mac OS X に標準に入っているライブラリ等でこのような属性を取り出せるかは失念しました。
> 漢字/変換を/しています/
>
> のように正しく分解してくれません。
「正しく」ですか。文法的な文節だとすると「しています」はもう少し分かれそうな気が... Language Analysis Manager
だとこういう区切りになるんしたっけ?
そういえば AppKit にマウスでダブルクリックをしたとき等の範囲を返すような API があった気がしますが、あれは純粋に文字種だけかもしれませんね。
純粋に日本語の文節ということでしたらとりあえずトークン分解を属性にしたがってまとめ上げたらいいはずですが... 別の方法もあるかもしれません。
On 2011/02/03, at 8:54, Yanagisawa wrote:
> え、訳がわかりませんか? それでは日本語の文法というものを意識されてみてはどうでしょう。
> Mac OS X の内部で使われているという噂の mecab を使うと
>
> 漢字 名詞,一般,*,*,*,*,漢字,カンジ,カンジ
> 変換 名詞,サ変接続,*,*,*,*,変換,ヘンカン,ヘンカン
> を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
> し 動詞,自立,*,*,サ変・スル,連用形,する,シ,シ
> て 助詞,接続助詞,*,*,*,*,て,テ,テ
> い 動詞,非自立,*,*,一段,連用形,いる,イ,イ
> ます 助動詞,*,*,*,特殊・マス,基本形,ます,マス,マス
>
> のようになります。形態素解析というやつですね。Spotlight でも使われているという噂です。
おお、形態素解析!! CFStringTokenizer はまちがってはいなかったのですね。
ただ、たとえば、ことえりで「漢字変換をしています」と入力すると
漢字/変換を/しています
というように文節(?)に分解してくれます。 わたしがしたいのはコレなんです。
そういえば、Language Analysis Manager の場合はいろいろな分解モードを選択できたような記憶があります。
CFStringTokenizerでは、名詞、動詞、助詞、助動詞などの属性情報がわからないので「トークン分解を属性にしたがってまとめ上げる」ことができないです。
うーむ。「噂の mecab 」というのを勉強してみます。
もう一度、CFStringTokenizer Reference をよく読んでみたら、こんな一説がありました。
The locale sensitivity of the tokenization unit options may change in future release.
柳沢さん、mecab についての貴重な情報ありがとうごさいました。m(_._)m
いちおう、のちのため記録として以下のようにまとめておきます。(^^;
日本語は 書類>文章>連文節>文節>形態素 のように分解できる。「文節」とは「文を読む際に自然な発音によって区切られる最小の単位」である。「形態素」とは「日本語として意味を持つ最小単位」のことである。CFStringTokenizer(Mac OS X 10.6.6)で日本語を分解したときの token とは「形態素」であり、現在の仕様では文節単位で分解することはできない。文節単位で分解するには、いろいろなフリーソフト(下記参照)を利用して可能である。
たとえば「漢字変換をしています」を分解すると、
文節では
漢字/変換を/しています
形態素では
漢字 名詞,一般,*,*,*,*,漢字,カンジ,カンジ
変換 名詞,サ変接続,*,*,*,*,変換,ヘンカン,ヘンカン
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
し 動詞,自立,*,*,サ変・スル,連用形,する,シ,シ
て 助詞,接続助詞,*,*,*,*,て,テ,テ
い 動詞,非自立,*,*,一段,連用形,いる,イ,イ
ます 助動詞,*,*,*,特殊・マス,基本形,ます,マス,マス
のように分解される。
<<参考>>
形態素
http://ja.wikipedia.org/wiki/%E5%BD%A2%E6%85%8B%E7%B4%A0
文節
http://mjin.doshisha.ac.jp/R/58/58.html