BreakIterator 在 Android 中如何工作?
How does BreakIterator work in Android?
我正在 Android(蒙古语的自定义垂直脚本 TextView)中制作自己的文本处理器。我以为我必须自己找到所有的换行位置才能实现换行,但后来我发现BreakIterator
。这似乎找到了各种语言中字符、单词、行和句子之间所有可能的断点。
我正在努力学习如何使用它。 documentation was more helpful than average, but it was still difficult to understand from just reading. I also found a few tutorials (see here, here, and here) 但他们缺乏我正在寻找的输出的完整解释。
我正在添加此问答式答案以帮助自己学习如何使用 BreakIterator
。
除了 Java 之外,我还把它设为 Android 标签,因为还有 apparently some difference between them. Also, Android now supports the ICU BreakIterator
,以后的答案可能会处理这个问题。
BreakIterator
可用于查找字符、单词、行和句子之间可能的中断。这对于将光标移动到可见字符、双击 select 个单词、三次单击 select 个句子和换行等操作很有用。
样板代码
以下示例中使用了以下代码。只需调整第一部分即可更改 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 .
最感兴趣的部分位于索引 6
、8
和 10
。您的浏览器可能会或可能不会正确显示字符,但用户会将所有这些解释为单个字符,即使它们由多个 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 。
这里有一些有趣的事情需要注意。首先,在 space 的两边检测到断字。其次,即使有不同的语言,multi-character 中文单词仍然被识别。即使我将语言环境设置为 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 示例。但是,现在白色 space 和标点符号包含在它前面的单词中。这是有道理的,因为您不希望新行以白色 space 或标点符号开头。另请注意,汉字会为每个字符换行。这与中文中跨行打断multi-character字是可以的是一致的
句子
更改样板代码以包含以下内容:
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 when you create a BreakIterator
, but if you don't it just uses the default locale.
进一步阅读
- Documentation
- ICU version of BreakIterator
- This 是比较有用的教程之一。
我正在 Android(蒙古语的自定义垂直脚本 TextView)中制作自己的文本处理器。我以为我必须自己找到所有的换行位置才能实现换行,但后来我发现BreakIterator
。这似乎找到了各种语言中字符、单词、行和句子之间所有可能的断点。
我正在努力学习如何使用它。 documentation was more helpful than average, but it was still difficult to understand from just reading. I also found a few tutorials (see here, here, and here) 但他们缺乏我正在寻找的输出的完整解释。
我正在添加此问答式答案以帮助自己学习如何使用 BreakIterator
。
除了 Java 之外,我还把它设为 Android 标签,因为还有 apparently some difference between them. Also, Android now supports the ICU BreakIterator
,以后的答案可能会处理这个问题。
BreakIterator
可用于查找字符、单词、行和句子之间可能的中断。这对于将光标移动到可见字符、双击 select 个单词、三次单击 select 个句子和换行等操作很有用。
样板代码
以下示例中使用了以下代码。只需调整第一部分即可更改 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 .
最感兴趣的部分位于索引 6
、8
和 10
。您的浏览器可能会或可能不会正确显示字符,但用户会将所有这些解释为单个字符,即使它们由多个 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 。
这里有一些有趣的事情需要注意。首先,在 space 的两边检测到断字。其次,即使有不同的语言,multi-character 中文单词仍然被识别。即使我将语言环境设置为 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 示例。但是,现在白色 space 和标点符号包含在它前面的单词中。这是有道理的,因为您不希望新行以白色 space 或标点符号开头。另请注意,汉字会为每个字符换行。这与中文中跨行打断multi-character字是可以的是一致的
句子
更改样板代码以包含以下内容:
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 when you create a BreakIterator
, but if you don't it just uses the default locale.
进一步阅读
- Documentation
- ICU version of BreakIterator
- This 是比较有用的教程之一。