`
liugang594
  • 浏览: 987514 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java国际化:BreakIterator

 
阅读更多

【译自: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();
}
分享到:
评论

相关推荐

    将汉字转换为汉语拼音java实现

    2. **ICU4J库**:国际组件库(ICU,International Components for Unicode)是一个强大的跨平台库,包含了许多与国际化相关的功能,包括汉字转拼音。在Java中,你可以通过引入ICU4J的依赖,然后使用`...

    java中文繁体转中文简体

    Java中的`java.text`包提供了处理字符和字符串的工具,其中包括`BreakIterator`、`Collator`、`DateFormat`、`NumberFormat`和`Normalizer`等类,它们在处理各种文本操作时非常有用。对于繁体到简体的转换,我们可以...

    JDK14-internationalization-guide.pdf

    《JDK14 国际化指南》是Oracle公司为Java开发者提供的关于Java平台标准版(Java SE)在第14版本中对于国际化支持的详细文档。这份指南旨在帮助开发者理解和利用Java 14中的国际化的特性,以便开发能够适应全球不同...

    translit.java:从剪贴板翻译俄语名称

    其次,Java的`java.text`包包含了用于国际化和本地化的类,其中`BreakIterator`可以用于分割字符串,`Collator`则用于比较字符串,而`Normalizer`则用于处理Unicode字符的规范化。在处理俄语名称时,可能需要利用`...

    JavaTexts:开发Java程序来处理语言

    在这个项目中,我们可以找到各种与文本分析、格式化、本地化以及国际化相关的功能。Java作为一种广泛使用的编程语言,其在处理文本方面的能力对于开发复杂的软件系统至关重要。下面,我们将深入探讨JavaTexts项目中...

    icu 4.6.1 src

    ICU的源代码包含了许多C++和Java两个主要部分,这些源码提供了丰富的函数库和类库,方便开发者在各自的编程环境中进行国际化和本地化操作。以下是一些核心模块的简要介绍: 1. **Unicode支持**:ICU提供了对Unicode...

    com.ibm.icu_4.4.2.v20110823.jar

    【描述】中提到的"com.ibm.icu_4.4.2.v20110823.jar" 是二进制版本的库,可以直接在Java应用程序中使用,以实现跨平台的国际化和本地化功能。而"com.ibm.icu.source_4.4.2.v20110823.jar"则是源代码版本,开发人员...

    android 简体转繁体,繁体转简体 代码 附sdk

    `java.text.BreakIterator`可以帮助你正确地分割和处理中文文本,而`java.text.Normalizer`则用于标准化Unicode字符串,确保在转换前后保持一致的格式。 4. **Android的TextUtils类**: Android SDK中的`android....

    安卓Android源码——中国地区选择.zip

    7. **国际化和本地化**: Android支持多语言和文化,`libcore/luni/src/main/java/java/util/Locale.java`和`java/text/BreakIterator.java`等文件处理文本的本地化和断词规则,中国地区可能有自己的断词规则和特殊...

    Eclipse部分源码

    ICU是一个跨平台的库,主要用于处理Unicode字符集和国际化(i18n)与本地化(l10n)问题。在Eclipse中,ICU扮演着重要角色,为Eclipse提供了对多种语言和文化的全面支持,包括日期、时间、数字格式、排序规则、文本...

    daima.rar_俄文

    在本文中,我们将深入探讨如何使用Java编程语言来输出俄文字母表,即所谓的“CYRILLIC”字母。这个程序对于学习Java编程并希望扩展到多语言支持的开发者来说非常有用...这些工具使得Java成为开发国际化软件的理想选择。

Global site tag (gtag.js) - Google Analytics