`

通过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

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    icu4c-52_1-src

    ICU4C是ICU在C/C++平台下的版本, ICU(International Component for Unicode)是基于"IBM公共许可证"的,与开源组织合作研究的, 用于支持软件国际化的开源项目。ICU4C提供了C/C++平台强大的国际化开发能力,软件开发者...

    icu4c-4_2_1-src(icu4c库)

    在项目中使用ICU4C,通常需要通过链接器将ICU库链接到你的程序中,并且在源代码中包含对应的头文件。例如,如果需要使用字符串操作,可以这样引入: ```cpp #include ``` 然后就可以使用ICU提供的API进行操作了。...

    icu4c-4_8_1_1-src.zip_ICU4C_bms_hindi_icu4c-4

    3. 头文件(h文件):定义了ICU4C的API,供开发者在自己的项目中调用。 4. 数据文件:可能包含Unicode数据,如字符映射表、区域设置信息等。 5. 示例和测试代码:帮助开发者理解如何使用ICU4C库进行实际开发。 总的...

    icu4c-4_8-Win32-msvc10

    ICU4C,全称是International Components for Unicode for C,是一个强大的开源库,主要用于处理Unicode字符集和全球化的任务。这个“icu4c-4_8-Win32-msvc10”压缩包包含了ICU4.8版本在Windows 32位平台上,使用...

    icu4c-68_2-Win32_64-MSVC2019.zip

    接着,通过包含头文件来引入ICU4C的API。例如,如果需要进行字符串转换,可以使用`#include <unicode/unistr.h>`。然后,可以调用如`UnicodeString`类的方法来处理字符串。同时,为了运行时支持,32位应用需要链接32...

    日文分词系统mecab的中文讲解

    Python和Java的使用方式类似,都是通过对应语言的API调用mecab的分词功能。 在获取每个词条的详细信息时,可以使用parseToNode方法,它返回句首的特殊词条,该词条是一个双向链表的节点,通过next和prev属性可以...

    icu for android

    在Android系统中,`icu4c-52_1-src.gz`文件包含的是ICU4C的源代码,版本为52.1。开发者可以下载并编译这个源代码来创建自定义的库,适应特定的Android项目需求。源代码包含各种类和函数,用于处理Unicode字符集、...

    Icu 配置使用说明

    通常,这涉及链接生成的库文件,并按照Icu的API调用进行编码转换等操作。请参考readme.html或其他相关的文档以获取更详细的集成指导。 总之,配置和使用Icu涉及下载正确版本的库,选择合适的资源文件打包方式,以及...

    android通过USB调用摄像头

    android通过USB外接摄像头这是一个例子,通过C调用底层驱动。在网上找过了例子总出现select timeout异常,改造解决了。有问题可以发邮件505738005.

    delphi调用结巴分词DLL接口

    2. 获取函数指针:通过`GetProcAddress`获取DLL中分词函数的地址。 3. 初始化:调用初始化函数,准备分词环境。 4. 分词操作:传入待分词的文本,调用分词函数,获取分词结果。 5. 错误处理:检查返回值,处理可能...

    康博嘉java笔试题-external_icu4c:external_icu4c

    6. **性能优化**:如果试题涉及到性能对比,候选人可能需要分析在Java应用中直接使用`ICU4J`和通过JNI调用`external_icu4c`的性能差异。 7. **源码阅读和理解**:开源库的使用可能涉及到阅读和理解源码,了解其实现...

    Qt JNI调用Android系统功能

    在Android开发中,JNI通常用来调用系统的低级功能或库,这些功能可能在Java层无法直接访问。 本文将深入探讨如何使用Qt的JNI功能来调用Android系统的特定功能,如震动、保持屏幕常亮、切换应用的横竖屏模式、调整...

    Android 下通过反射调用加载/卸载(mount/unmount) 外置SD卡

    要通过反射调用加载和卸载外置SD卡,我们需要访问Android系统的私有API,因为这些操作不在官方的SDK中公开。具体来说,我们关注的核心类是`MountService`,它是负责设备挂载和卸载的核心组件。 1. **`IMountService...

    android中Webview与javascript的交互(互相调用)

    总之,Android中的WebView与JavaScript的交互是通过暴露Java对象和调用JavaScript函数实现的,这种方式极大地丰富了Android应用的功能。在实际开发中,我们需要合理利用这一特性,同时注意安全性和性能优化。

    Android通过Java接口调用OpenCV2.4示例

    本文将深入探讨如何在Android应用中通过Java接口调用OpenCV 2.4版本,以实现将图片转换为灰度图的功能。 首先,我们需要理解OpenCV的基本概念。OpenCV(Open Source Computer Vision Library)是一个跨平台的计算机...

    QT通过QProcess调用外部可执行程序,并将其嵌入到主窗口中

    让我们深入探讨如何在QT中通过QProcess调用外部可执行程序并将其嵌入到主窗口中。 首先,了解QProcess的基本用法。QProcess允许我们启动一个外部进程,监控它的状态,读取其标准输出和错误输出,甚至可以向进程发送...

    Android和Unity3d互相调用的Demo

    调用时,通过Unity的DllImport函数调用Android插件的方法,从而执行Android端的功能。 本Demo中的“中间件”可能是实现这种交互的关键组件。它可能是一个封装了调用逻辑的库,帮助简化Android和Unity3D之间的通信...

    android 通过usb调用UVC摄像头

    android USB调用摄像头,经过半月时间终于搞定了, 在网上找了好多,还有日文注释的 希望段友多多包涵,首先手机支持uvc 测试机 荣耀8. 我也是在网上找啊找,如何谁在学习接触这方面,共同学习,

    qt-android调用静态库和动态库例子

    在Android平台上进行Qt开发时,有时我们需要调用C++库来扩展功能,这些...通过以上步骤,你应该能够在Qt for Android项目中成功地调用静态库和动态库。记得在开发过程中进行充分的测试,确保在不同设备上都能正常运行。

    Android中JS与Java相互调用Demo

    这样,JavaScript就可以通过`window.android`来调用`MyJavaScriptInterface`中的方法了。 2. **Java调用JavaScript**: Android的`WebView`提供了`loadUrl()`方法,可以用来执行JavaScript代码。例如,如果你想...

Global site tag (gtag.js) - Google Analytics