`

通过BreakIterator调用Android的icu4c执行中日文的粗略“分词”

阅读更多

    发现Android自带的icu4c可以直接使用,不需要自己编译它。它的JNI接口可以用java.text包下的类间接调用。

    我感兴趣的是icu4c的范围分析功能,即所谓的分词,例如,可以用java.text.BreakIterator实现日文和中文粗略分词(前提是需要事先指定其语言区域,不过后来实测发现日文的分词效果并不如专门的分词库那么好)。官方文档中有一个使用示例,用起来也非常方便:

 

package com.iteye.weimingtom.icutest;

import java.text.BreakIterator;
import java.util.Locale;

import android.app.Activity;
import android.os.Bundle;

public class ICUTestActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        final String testStr = "残忍で破壊的な性格がチャームポイントな本作の主人公[6][7]。" + 
            	"真尋にひと目惚れし、それ以来、" + 
            	"下心を隠そうともせず猛アタックを続けている。";
        System.out.println("日文范围划分");
        test(Locale.JAPAN, testStr);
        System.out.println("中文范围划分");
        test(Locale.CHINA, testStr);
/*

08-15 19:05:24.825: I/System.out(9011): 日文范围划分
08-15 19:05:24.835: I/System.out(9011): 残忍
08-15 19:05:24.835: I/System.out(9011): で
08-15 19:05:24.845: I/System.out(9011): 破壊的
08-15 19:05:24.845: I/System.out(9011): な
08-15 19:05:24.845: I/System.out(9011): 性格
08-15 19:05:24.845: I/System.out(9011): が
08-15 19:05:24.845: I/System.out(9011): チャームポイント
08-15 19:05:24.845: I/System.out(9011): な
08-15 19:05:24.845: I/System.out(9011): 本作
08-15 19:05:24.845: I/System.out(9011): の
08-15 19:05:24.845: I/System.out(9011): 主人公
08-15 19:05:24.845: I/System.out(9011): [
08-15 19:05:24.845: I/System.out(9011): 6
08-15 19:05:24.845: I/System.out(9011): ]
08-15 19:05:24.855: I/System.out(9011): [
08-15 19:05:24.855: I/System.out(9011): 7
08-15 19:05:24.855: I/System.out(9011): ]
08-15 19:05:24.855: I/System.out(9011): 。
08-15 19:05:24.855: I/System.out(9011): 真尋
08-15 19:05:24.855: I/System.out(9011): にひと
08-15 19:05:24.855: I/System.out(9011): 目惚
08-15 19:05:24.855: I/System.out(9011): れし
08-15 19:05:24.865: I/System.out(9011): 、
08-15 19:05:24.865: I/System.out(9011): それ
08-15 19:05:24.865: I/System.out(9011): 以来
08-15 19:05:24.865: I/System.out(9011): 、
08-15 19:05:24.865: I/System.out(9011): 下心
08-15 19:05:24.865: I/System.out(9011): を
08-15 19:05:24.865: I/System.out(9011): 隠
08-15 19:05:24.865: I/System.out(9011): そうともせず
08-15 19:05:24.865: I/System.out(9011): 猛
08-15 19:05:24.865: I/System.out(9011): アタック
08-15 19:05:24.865: I/System.out(9011): を
08-15 19:05:24.865: I/System.out(9011): 続
08-15 19:05:24.865: I/System.out(9011): けている
08-15 19:05:24.865: I/System.out(9011): 。




08-15 19:05:24.865: I/System.out(9011): 中文范围划分
08-15 19:05:24.885: I/System.out(9011): 残
08-15 19:05:24.885: I/System.out(9011): 忍
08-15 19:05:24.885: I/System.out(9011): で
08-15 19:05:24.885: I/System.out(9011): 破
08-15 19:05:24.885: I/System.out(9011): 壊
08-15 19:05:24.885: I/System.out(9011): 的
08-15 19:05:24.885: I/System.out(9011): な
08-15 19:05:24.885: I/System.out(9011): 性
08-15 19:05:24.885: I/System.out(9011): 格
08-15 19:05:24.885: I/System.out(9011): が
08-15 19:05:24.885: I/System.out(9011): チャームポイント
08-15 19:05:24.885: I/System.out(9011): な
08-15 19:05:24.885: I/System.out(9011): 本
08-15 19:05:24.885: I/System.out(9011): 作
08-15 19:05:24.885: I/System.out(9011): の
08-15 19:05:24.885: I/System.out(9011): 主
08-15 19:05:24.885: I/System.out(9011): 人
08-15 19:05:24.885: I/System.out(9011): 公
08-15 19:05:24.885: I/System.out(9011): [
08-15 19:05:24.885: I/System.out(9011): 6
08-15 19:05:24.885: I/System.out(9011): ]
08-15 19:05:24.885: I/System.out(9011): [
08-15 19:05:24.885: I/System.out(9011): 7
08-15 19:05:24.885: I/System.out(9011): ]
08-15 19:05:24.885: I/System.out(9011): 。
08-15 19:05:24.885: I/System.out(9011): 真
08-15 19:05:24.885: I/System.out(9011): 尋
08-15 19:05:24.885: I/System.out(9011): に
08-15 19:05:24.885: I/System.out(9011): ひ
08-15 19:05:24.885: I/System.out(9011): と
08-15 19:05:24.885: I/System.out(9011): 目
08-15 19:05:24.895: I/System.out(9011): 惚
08-15 19:05:24.895: I/System.out(9011): れ
08-15 19:05:24.895: I/System.out(9011): し
08-15 19:05:24.895: I/System.out(9011): 、
08-15 19:05:24.895: I/System.out(9011): そ
08-15 19:05:24.895: I/System.out(9011): れ
08-15 19:05:24.895: I/System.out(9011): 以
08-15 19:05:24.905: I/System.out(9011): 来
08-15 19:05:24.905: I/System.out(9011): 、
08-15 19:05:24.905: I/System.out(9011): 下
08-15 19:05:24.905: I/System.out(9011): 心
08-15 19:05:24.905: I/System.out(9011): を
08-15 19:05:24.905: I/System.out(9011): 隠
08-15 19:05:24.905: I/System.out(9011): そ
08-15 19:05:24.905: I/System.out(9011): う
08-15 19:05:24.905: I/System.out(9011): と
08-15 19:05:24.905: I/System.out(9011): も
08-15 19:05:24.905: I/System.out(9011): せ
08-15 19:05:24.905: I/System.out(9011): ず
08-15 19:05:24.905: I/System.out(9011): 猛
08-15 19:05:24.905: I/System.out(9011): アタック
08-15 19:05:24.905: I/System.out(9011): を
08-15 19:05:24.905: I/System.out(9011): 続
08-15 19:05:24.905: I/System.out(9011): け
08-15 19:05:24.905: I/System.out(9011): て
08-15 19:05:24.915: I/System.out(9011): い
08-15 19:05:24.915: I/System.out(9011): る
08-15 19:05:24.915: I/System.out(9011): 。

 */
        
    }
    
    /**
     * @see http://developer.android.com/reference/java/text/BreakIterator.html
     * @param where
     * @param stringToExamine
     */
    private static void test(Locale where, String stringToExamine) {
        BreakIterator boundary = BreakIterator.getWordInstance(where);
        boundary.setText(stringToExamine);
        int start = boundary.first();
        for (int end = boundary.next(); 
        	end != BreakIterator.DONE; 
        		start = end, end = boundary.next()) {
            System.out.println(stringToExamine.substring(start, end));
        }
    }
}

 

 

PS:可能缺少一些区域,需要事先作判断。

 

 

				boolean hasJapanLocal = false;
				Locale[] locales = BreakIterator.getAvailableLocales();
				if (locales != null) {
					for (Locale locale : locales) {
						if (D) {
							Log.d(TAG, "locale: " + locale.toString());
						}
						if (locale != null && locale.equals(Locale.JAPAN)) {
							hasJapanLocal = true;
							break;
						}
					}
				}
 

 

参考资料:

1.  Android官方文档

http://developer.android.com/reference/java/text/BreakIterator.html

 

2. icu4c的官方文档

http://userguide.icu-project.org/boundaryanalysis

 

3. Android源代码中的测试代码

http://www.oschina.net/code/explore/android-2.2-froyo/org/apache/harmony/text/tests/java/text/BreakIteratorTest.java

 

4. chrome使用的开源工程介绍

http://my.oschina.net/yaraja/blog/32521

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics