2017-02-14 47 views
2

我正在Android中創建自己的文本處理器(一個自定義垂直腳本TextView for Mongolian)。我以爲自己必須自己找到所有的換行位置,這樣才能實現換行,但後來我發現了BreakIterator。這似乎找到了各種語言中字符,單詞,行和句子之間所有可能的中斷。BreakIterator如何在Android中工作?

我在學習如何使用它。 documentation比平均值更有幫助,但從閱讀起仍然很難理解。我還發現了一些教程(請參閱here,herehere),但他們缺少完整的解釋並輸出了我正在尋找的內容。

我在添加此Q &風格答案以幫助我學習如何使用BreakIterator

除了Java之外,我還將其製作爲Android標記,因爲它們之間有apparently some difference。此外,Android現在支持ICU BreakIterator,未來的答案可能會解決這個問題。

回答

4

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; 
} 

如果你只是想測試這一點,你可以直接將其粘貼到一個活動的onCreate在Android中。我使用的是System.out.println而不是Log,因此它也可以在僅Java環境中測試。

我使用的是java.text.BreakIterator而非ICU,它只能從API 24中獲得。請參閱底部的鏈接瞭解更多信息。

人物

更改樣板代碼包括以下

String text = "English中文123éé\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 果。 

注意,斷裂位置沒有文字的整行。它們只是方便文字排線的地方。

輸出與單詞示例類似。但是,現在的白色空間和標點符號都包含在它之前的單詞中。這是有道理的,因爲你不希望新的行以空格或標點符號開頭。另請注意,漢字會爲每個字符換行。這符合這樣一個事實,即可以在中文中跨行打破多字符單詞。

更改樣板代碼包括以下內容:

String text = "I like to eat apples. My email is [email protected]\n" + 
     "This is a new paragraph. 我喜歡吃蘋果。我不愛吃臭豆腐。"; 
BreakIterator boundary = BreakIterator.getSentenceInstance(); 

輸出

image to represent text output

正確的句子分解多種語言得到了承認。此外,電子郵件域中的點沒有誤報。

您可以設置Locale當你創建一個BreakIterator,但如果你不這樣做,它只是使用了default locale

進一步閱讀

+0

將中文文本分解爲單詞對我來說工作不正常。你能看看https://stackoverflow.com/questions/44507838/breakiterator-not-working-correctly-with-chinese-text嗎? – srgsanky