Java国际化:BreakIterator

标签: java 国际化 breakiterator | 发表时间:2014-03-21 11:51 | 作者:liugang594
出处:http://www.iteye.com

【译自:http://tutorials.jenkov.com/java-internationalization/breakiterator.html , 不准确别怪我】

java.text.BreakIterator 类用来查找不同语言中的字符、单词和句子的边界。因为不同的语言有不同的字、单词和句子的边界,所以只是查找空格、逗号、句号、分号和冒号是不够的。你需要一个万无一失的、可用于各种语言的查找方法。 BreakIterator 类就是干这个的。

创建一个 BreakIterator

一个  BreakIterator 实例只能判断以下四种边界之一:

  • 字符边界
  • 单词边界
  • 句子边界
  • 行边界

首先需要使用BreakIterator类提供的用于识别以上边界的,对应的工厂方法来创建一个实例。这些工厂方法有:

BreakIterator.getCharacterInstance();
BreakIterator.getWordInstance();
BreakIterator.getSentenceInstance();
BreakIterator.getLineInstance();

每个方法都需要一个  Locale 作为参数,然后返回一个  BreakIterator 实例,例如:

Locale locale = LocaleUK;

BreakIterator breakIterator =
    BreakIterator.characterInstance(locale);

字符边界

当查找一个字符边界时,需要区分用户字符和Unicode字符。

一个用户字符是指用户用笔书写时或者用户通常在屏幕上看到了字符。

一个用户字符通常需要一个或多个Unicode字符去表示;有的需要2个或更多的Unicode字符来表示。

一个  BreakIterator 的字符实例可以用于查找用户字符的边界,而不是Unicode字符。

例如,以下例子用来查找一个字符串的字符边界:

Locale locale = Locale.UK;
BreakIterator breakIterator =
        BreakIterator.getCharacterInstance(locale);

breakIterator.setText("Mary had a little Android device.");

int boundaryIndex = breakIterator.first();
while(boundaryIndex != BreakIterator.DONE) {
    System.out.println(boundaryIndex) ;
    boundaryIndex = breakIterator.next();
}

上例创建了一个用于英式英语的  BreakIterator 实例,然后调用 setText() 方法指定用于查找的文本内容。

first() 方法返回找到的第一个断点,方法  next() 用于查找所有接下来的断点。这两个方法都返回查找到的用户字符中的Unicode字符索引。因此,如果一个用户字符占用了多于一个的Unicode字符,那么字符的索引会增加占用的Unicode字符数。

单词边界

当查找单词时,需要创建一个符合单词边界的、针对特定语言的 BreakIterator 实例,下面是一个示例:

Locale locale = Locale.UK;
BreakIterator breakIterator =
        BreakIterator.getWordInstance(locale);
以上代码创建一个用于查找英国英语中单词边界的  BreakIterator 实例。

下面的例子演示了怎么查找一段英语文本的单词边界:

Locale locale = Locale.UK;
BreakIterator breakIterator =
        BreakIterator.getWordInstance(locale);

breakIterator.setText("Mary had a little Android device.");

int boundaryIndex = breakIterator.first();
while(boundaryIndex != BreakIterator.DONE) {
    System.out.println(boundaryIndex) ;
    boundaryIndex = breakIterator.next();
}

同样的, first() 和  next() 方法返回查找到单词的Unicode字符的索引。

用Java统计特定语言中的单词数Counting Words in a Specific Language in Java

这个Java代码片段显示了如果统计某个特定语言中的单词数:

public class WordCounter {

    public static class  WordCount {
        protected String word  = null;
        protected int    count = 0;
    }

    public static Map<String, WordCount> countWords(String text, Locale locale) {
        Map<String, WordCount> wordCounts = new HashMap<String, WordCount>();

        BreakIterator breakIterator = BreakIterator.getWordInstance(locale) ;
        breakIterator.setText(text);

        int wordBoundaryIndex = breakIterator.first();
        int prevIndex         = 0;
        while(wordBoundaryIndex != BreakIterator.DONE){
            String word = text.substring(prevIndex, wordBoundaryIndex).toLowerCase();
            if(isWord(word)) {
                WordCount wordCount = wordCounts.get(word);
                if(wordCount == null) {
                    wordCount = new WordCount();
                    wordCount.word = word;
                }
                wordCount.count++;
                wordCounts.put(word, wordCount);
            }
            prevIndex = wordBoundaryIndex;
            wordBoundaryIndex = breakIterator.next();
        }

        return wordCounts;
    }

    private static boolean isWord(String word) {
        if(word.length() == 1){
            return Character.isLetterOrDigit(word.charAt(0));
        }
        return !"".equals(word.trim());
    }
}

方法 countWords() 需要一个 string 参数和一个  Locale 参数。 Locale 代码了传入的string的语言类别。因此,当创建  BreakIterator,它可以创建针对那个语言类型的实例。

这个方法统计了一个单词在传入的串中有多少个,然后返回一个  Map<String, WordCount> 对象,Map中的key是一个一个单词,以小写形式表示,值是一个  WordCount 实例,它包含了两个变量: word 和  count 。只需要把所有的单词发生的次数相加就可以得到总的单词数了。

注意: isWord() 方法中是怎么使用  Character.isLetterOrDigit() 方法来判断某个字符是字母还是数字的,或者是其他的(例如分号,引号等)。 Character.isLetterOrDigit()方法检查对应的unicode characters 是字母还是数字,并且不仅仅用在英语上,也可以用于其他语言。关于这个方法和其他的一些类似的方法的更详细的描述,可以参考: Characeter Methods 。

句子边界

对于特定语言的句子边界,需要创建一个 BreakIterator 针对那种语言的句子边界实例:

Locale locale = Locale.UK;
BreakIterator breakIterator =
        BreakIterator.getSentenceInstance(locale);
以上代码创建了一个针对英国英语的  BreakIterator 句子实例。

以下示例查找英语文本中的句子边界:

Locale locale = Locale.UK;
BreakIterator breakIterator =
        BreakIterator.getSentenceInstance(locale);

breakIterator.setText(
        "Mary had a little Android device. " +
        "It had small batteries too.");

int boundaryIndex = breakIterator.first();
while(boundaryIndex != BreakIterator.DONE) {
    System.out.println(boundaryIndex) ;
    boundaryIndex = breakIterator.next();
}

行边界

也可以查找某段文本中的新行而不中断文本的阅读。这个时候需要一个拥有用于侦探潜在的行边界的 BreakIterator 实例。注意:这并不能找到直接的行断点,而是潜在的行断点。找到潜在的行中断是需要把文本划分成多行显示的时候相当有用,即使这段文本不包括任何显示的分行。以下是一个创建这个的  BreakIterator 实例的例子:

Locale locale = Locale.UK;
BreakIterator breakIterator =
        BreakIterator.getLineInstance(locale);

这个例子创建一个拥有英式英语的潜在的行分割通用的  BreakIterator 实例。

下面的例子用于查找潜在的行分割:

Locale locale = Locale.UK;
BreakIterator breakIterator =
        BreakIterator.getLineInstance(locale);

breakIterator.setText(
        "Mary had a little Android device.\n " +
        "It had small batteries too.");

int boundaryIndex = breakIterator.first();
while(boundaryIndex != BreakIterator.DONE) {
    System.out.println(boundaryIndex) ;
    boundaryIndex = breakIterator.next();
}


已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [java 国际化 breakiterator] 推荐:

Java国际化:BreakIterator

- - 编程语言 - ITeye博客
【译自:http://tutorials.jenkov.com/java-internationalization/breakiterator.html , 不准确别怪我】. java.text.BreakIterator 类用来查找不同语言中的字符、单词和句子的边界. 因为不同的语言有不同的字、单词和句子的边界,所以只是查找空格、逗号、句号、分号和冒号是不够的.

Chrome插件的国际化技巧

- iBeyond - keakon的涂鸦馆
今天在查看Proxy SwitchySharp的源码时,看到了一个国际化的技巧. 觉得很不错,于是给Sync My Tabs插件增加了国际化支持,并在此分享. 其实之前我在做Chrome插件时都有个疑点,翻译JavaScript里的文字用Chrome的i18n API很容易,但是要翻译HTML就麻烦了,毕竟动态生成HTML没有静态的方便.

业务层资源国际化处理

- - CSDN博客推荐文章
用过struts2等mvc框架开发的同学都知道,使用struts2处理国际化的消息非常简单直观,但是mvc框架的定位是在展示层(jsp,action)等,在一个典型的3层结构中,处于最上层的位置,按照分层设计原则,下层组件是不可以调用上层组件的,这样就存在一个问题,我们在业务层中可能也会出现一些需要国际化处理的消息信息,这些信息如何设置呢.

Java中的锁(Locks in Java)

- - 并发编程网 - ifeve.com
原文链接 作者:Jakob Jenkov 译者:申章 校对:丁一. 锁像synchronized同步块一样,是一种线程同步机制,但比Java中的synchronized同步块更复杂. 因为锁(以及其它更高级的线程同步机制)是由synchronized同步块的方式实现的,所以我们还不能完全摆脱synchronized关键字( 译者注:这说的是Java 5之前的情况).

Java PaaS 对决

- 呆瓜 - IBM developerWorks 中国 : 文档库
本文为 Java 开发人员比较了三种主要的 Platform as a Service (PaaS) 产品:Google App Engine for Java、Amazon Elastic Beanstalk 和 CloudBees RUN@Cloud. 它分析了每种服务独特的技术方法、优点以及缺点,而且还讨论了常见的解决方法.

Java浮点数

- d0ngd0ng - 译言-电脑/网络/数码科技
Thomas Wang, 2000年3月. Java浮点数的定义大体上遵守了二进制浮点运算标准(即IEEE 754标准). IEEE 754标准提供了浮点数无穷,负无穷,负零和非数字(Not a number,简称NaN)的定义. 在Java开发方面,这些东西经常被多数程序员混淆. 在本文中,我们将讨论计算这些特殊的浮点数相关的结果.

Qt——转战Java?

- - 博客 - 伯乐在线
编者按:事实上,在跨平台开发方面,Qt仍是最好的工具之一,无可厚非,但Qt目前没有得到任何主流移动操作系统的正式支持. 诺基亚的未来计划,定位非常模糊,这也是令很多第三方开发者感到失望,因此将导致诺基亚屡遭失败的原因. Qt的主要开发者之一Mirko Boehm在博客上强烈讽刺Nokia裁了Qt部门的决定,称其为“绝望之举”,而非“策略变更”.

java 验证码

- - ITeye博客
// 创建字体,字体的大小应该根据图片的高度来定. // 随机产生160条干扰线,使图象中的认证码不易被其它程序探测到. // randomCode用于保存随机产生的验证码,以便用户登录后进行验证. // 随机产生codeCount数字的验证码. // 得到随机产生的验证码数字. // 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同.

Java异常

- - CSDN博客推荐文章
“好的程序设计语言能够帮助程序员写出好程序,但是无论哪种语言都避免不了程序员写出坏的程序.                                                                                                                          ----《Java编程思想》.

java面试题

- - Java - 编程语言 - ITeye博客
 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面. 抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节. 抽象包括两个方面,一是过程抽象,二是数据抽象.  继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法. 对象的一个新类可以从现有的类中派生,这个过程称为类继承.