java - BreakIterator 在 Android 中如何工作?

标签 java android word-wrap breakiterator

我正在 Android 中制作自己的文本处理器(蒙古语的自定义垂直脚本 TextView)。我以为我必须自己找到所有换行位置才能实现换行,但后来我发现了 BreakIterator .这似乎找到了各种语言中字符、单词、行和句子之间所有可能的断点。

我正在努力学习如何使用它。 documentation比一般人更有帮助,但仅通过阅读仍然难以理解。我还找到了一些教程(请参阅 hereherehere),但它们缺少我正在寻找的输出的完整解释。

我添加这个问答式的答案是为了帮助自己学习如何使用 BreakIterator

除了 Java,我将其设为 Android 标签,因为有 apparently some difference它们之间。此外,Android 现在支持 ICU BreakIterator future 的答案可能会解决这个问题。

最佳答案

BreakIterator 可用于查找字符、单词、行和句子之间可能的中断。这对于将光标移动到可见字符、双击以选择单词、三次单击以选择句子和换行等操作非常有用。

样板代码

以下示例中使用了以下代码。只需调整第一部分即可更改 BreakIterator 的文本和类型。

// change these two lines for the following examples
String text = "This is some text.";
BreakIterator boundary = BreakIterator.getCharacterInstance();

// boiler plate code
boundary.setText(text);
int start = boundary.first();
for (int end = boundary.next(); end != BreakIterator.DONE; end = boundary.next()) {
    System.out.println(start + " " + text.substring(start, end));
    start = end;
}

如果您只是想对此进行测试,您可以将其直接粘贴到 Android 中 Activity 的 onCreate 中。我使用的是 System.out.println 而不是 Log,因此它也可以在纯 Java 环境中进行测试。

我使用的是 java.text.BreakIterator 而不是 ICU,它只能从 API 24 获得。有关详细信息,请参阅底部的链接。

字符

更改样板代码以包含以下内容

String text = "Hi 中文éé\uD83D\uDE00\uD83C\uDDEE\uD83C\uDDF3.";
BreakIterator breakIterator = BreakIterator.getCharacterInstance();

输出

0 H
1 i
2  
3 中
4 文
5 é
6 é
8 😀
10 🇮🇳
14 .

最感兴趣的部分位于索引 6810。您的浏览器可能会或可能不会正确显示字符,但用户会将所有这些字符解释为单个字符,即使它们由多个 UTF-16 值组成。

字词

更改样板代码以包含以下内容:

String text = "I like to eat apples. 我喜欢吃苹果。";
BreakIterator boundary = BreakIterator.getWordInstance();

输出

0 I
1  
2 like
6  
7 to
9  
10 eat
13  
14 apples
20 .
21  
22 我
23 喜欢
25 吃
26 苹果
28 。

这里有一些有趣的事情需要注意。首先,在空格的两边检测到分词。其次,即使有不同的语言,多字符的中文单词仍然被识别。即使我将区域设置设置为 Locale.US,这在我的测试中仍然是正确的。

线条

您可以保持与单词示例相同的代码:

String text = "I like to eat apples. 我喜欢吃苹果。";
BreakIterator boundary = BreakIterator.getLineInstance();

输出

0 I 
2 like 
7 to 
10 eat 
14 apples. 
22 我
23 喜
24 欢
25 吃
26 苹
27 果。

请注意,中断位置不是整行文本。它们只是换行文本的方便位置。

输出类似于 Words 示例。但是,现在空格和标点符号包含在它前面的单词中。这是有道理的,因为您不希望新行以空格或标点符号开头。另请注意,汉字会为每个字符换行。这与中文中多字词跨行分行是可以的是一致的。

句子

更改样板代码以包含以下内容:

String text = "I like to eat apples. My email is me@example.com.\n" +
        "This is a new paragraph. 我喜欢吃苹果。我不爱吃臭豆腐。";
BreakIterator boundary = BreakIterator.getSentenceInstance();

输出

0 I like to eat apples. 
22 My email is me@example.com.
50 This is a new paragraph. 
75 我喜欢吃苹果。
82 我不爱吃臭豆腐。

可以在多种语言中识别正确的断句。此外,电子邮件域中的点没有误报。

注意事项

您可以设置 Locale当您创建一个 BreakIterator 时,但如果您不这样做,它只会使用 default locale .

进一步阅读

关于java - BreakIterator 在 Android 中如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42219292/

相关文章:

java - Eclipse 调试 View 当前行

android - Android EditText 中的文本在 WebView 中变成垃圾字符

android - 改造 : deal with property that can be either empty string or an array

android - 如何在 AndroidManifest.xml 中隐藏 API key

html - 在可伸缩表格中包装文本

javascript - 获取 TD 单元格宽度以指定宽度 % 环绕 div

java - JPanel 宽度超过 getPreferredSize() 中定义的尺寸

java - 如何在java中编辑.yml文件?

java - 如何包装添加到网格列内的标签文本?

java - Selenium:setHeadless() 对 ChromeDriver 没有影响