BreakIterator如何在Android中运行?

Sur*_*gch 5 java android word-wrap breakiterator

我正在Android中创建自己的文本处理器(一个自定义垂直脚本TextView for Mongolian).我想我必须自己找到所有的断线位置,以便我可以实现换行,但后来我发现了BreakIterator.这似乎找到了各种语言中的字符,单词,行和句子之间的所有可能的中断.

我正在努力学习如何使用它.该文件是超过平均水平有帮助,但它仍然难以从只是阅读理解.我还找到了一些教程(见这里,这里这里),但他们缺乏我正在寻找的输出的完整解释.

我正在添加这个Q&A风格的答案,以帮助自己学习如何使用BreakIterator.

除了Java之外,我正在制作这个Android标签,因为它们之间显然存在一些差异.此外,Android现在支持ICUBreakIterator,未来的答案可能会解决这个问题.

Sur*_*gch 11

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

Boilerplate代码

以下示例中使用了以下代码.只需调整第一部分即可更改文本和类型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;
}
Run Code Online (Sandbox Code Playgroud)

如果您只是想测试一下,可以直接将其粘贴到onCreateAndroid 的Activity 中.我正在使用System.out.println而不是Log在Java环境中也可以测试它.

我使用的java.text.BreakIterator是ICU,而不是IC24.请参阅底部的链接以获取更多信息.

人物

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

String text = "Hi ??ée?\uD83D\uDE00\uD83C\uDDEE\uD83C\uDDF3.";
BreakIterator breakIterator = BreakIterator.getCharacterInstance();
Run Code Online (Sandbox Code Playgroud)

产量

0 H
1 i
2  
3 ?
4 ?
5 é
6 e?
8 
10 
14 .
Run Code Online (Sandbox Code Playgroud)

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

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

String text = "I like to eat apples. ???????";
BreakIterator boundary = BreakIterator.getWordInstance();
Run Code Online (Sandbox Code Playgroud)

产量

0 I
1  
2 like
6  
7 to
9  
10 eat
13  
14 apples
20 .
21  
22 ?
23 ??
25 ?
26 ??
28 ?
Run Code Online (Sandbox Code Playgroud)

这里有一些有趣的事情需要注意.首先,在空间的两侧检测到断字.其次,即使有不同的语言,仍然可以识别出多字符的中文单词.即使我将语言环境设置为,在我的测试中仍然如此Locale.US.

您可以保持代码与Words示例相同:

String text = "I like to eat apples. ???????";
BreakIterator boundary = BreakIterator.getLineInstance();
Run Code Online (Sandbox Code Playgroud)

产量

0 I 
2 like 
7 to 
10 eat 
14 apples. 
22 ?
23 ?
24 ?
25 ?
26 ?
27 ??
Run Code Online (Sandbox Code Playgroud)

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

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

句子

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

String text = "I like to eat apples. My email is me@example.com.\n" +
        "This is a new paragraph. ???????????????";
BreakIterator boundary = BreakIterator.getSentenceInstance();
Run Code Online (Sandbox Code Playgroud)

产量

0 I like to eat apples. 
22 My email is me@example.com.
50 This is a new paragraph. 
75 ???????
82 ????????
Run Code Online (Sandbox Code Playgroud)

以多种语言识别正确的句子休息时间.此外,电子邮件域中的点没有误报.

笔记

您可以在创建时设置区域设置BreakIterator,但如果不这样做,则只使用默认区域设置.

进一步阅读