2010年11月11日木曜日

MacOS X 10.6にデフォルトで入っているlibmecab.dylib ( MeCab )を使ってみた

追記(2011/2/4): FYI 'Google groups / cocoa-dev-japan / 日本語文字列を文節に分解するには?'

追記2(2010/11/12): lengthOfBytesUsingEncodingで文字列の長さを出してmecab_sparse_tonode2を用いることで解決.参考サイトの通りに作ればちゃんと動く.

追記(2010/11/12): 半角が入ると止まる.mecabさんの設定になにかする必要があるのかしら…。CFStringTransformで「全角から半角」の逆変換をかけてUTF16LEへ変換して,mecabへ入れてみたが,あまりうまくいってない.



動機
なんとなく.


やってみた
0.Cocoaプロジェクトを作る('Untitled').
1./usr/libをFinderで開き(コンソールで'open /usr/lib'とかする),libmecab.dylibをDnDにてプロジェクトに追加.(コピーはしない)
2.コードを書く
UntitledAppDelegate.h
#import <Cocoa/Cocoa.h>
#include "mecab.h"

@interface UntitledAppDelegate : NSObject <NSApplicationDelegate> {
NSWindow *window;

mecab_t *mecab;
NSString *_inputString;
NSArray *_mecabResult;
}
@property (assign) IBOutlet NSWindow *window;
@end

UntitledAppDelegate.m
#import "UntitledAppDelegate.h"
@implementation UntitledAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
mecab = mecab_new2("-d /usr/lib/mecab/dic/apple/ja/LE");
if (mecab == NULL) {
fprintf(stderr, "error in mecab_new2: %s\n", mecab_strerror(NULL));
}
}
- (void)dealloc
{
mecab_destroy(mecab);
[super dealloc];
}
- (NSString *)inputString
{
return [[_inputString retain] autorelease];
}
- (void)setInputString:(NSString *)inputString
{
[_inputString release];
_inputString= [inputString retain];
[self setMecabResult:[self mecabResultWithString:_inputString]];
}
- (NSArray *)mecabResult
{
return [[_mecabResult retain] autorelease];
}
- (void)setMecabResult:(NSArray *)mecabResult
{
[_mecabResult release];
_mecabResult= [mecabResult retain];
}
- (NSArray *)mecabResultWithString:(NSString *)input
{
NSMutableArray *ret= [NSMutableArray array];
if (input==nil || [input length]==0)
return ret;
const char *buf= [input cStringUsingEncoding:NSUTF16LittleEndianStringEncoding];
const mecab_node_t *node = mecab_sparse_tonode(mecab, buf);
NSUInteger l= [input lengthOfBytesUsingEncoding:NSUTF16LittleEndianStringEncoding];
const mecab_node_t *node = mecab_sparse_tonode2(mecab, buf, l);
if (node == NULL) {
return ret;
}

node = node->next;
for (; node->next != NULL; node = node->next) {
NSString *w = [[NSString alloc] initWithBytes:node->surface
length:node->length
encoding:NSUTF16LittleEndianStringEncoding];
[ret addObject:w];
[w release];
}
return ret;
}
@end

3.IBにてNSTextFiledとNSTokenFieldを配置.
4.IBにて上記それぞれのインスペクタ/Bindingsタブにてvalue属性についてUntitledAppDelegateに対してModel Key PathをinputString, mecabResultと設定する.
5.実行

実行

参考サイト
感謝!
きまぐれ日記: Mac OS X Leopard に「標準で」インストールされている MeCabを使ってみる

0 件のコメント: