Как работает BreakIterator в Android?
Я делаю свой собственный текстовый процессор в Android (собственный вертикальный скрипт TextView для монгольского). Я думал, что мне придется найти все линии, разбивающие локации, чтобы я мог реализовать перенос строк, но затем я обнаружил BreakIterator
. Кажется, это находит все возможные разрывы между символами, словами, строками и предложениями на разных языках.
Я пытаюсь научиться его использовать. Документация была более полезной, чем средняя, но ее было трудно понять, просто прочитав. Я также нашел несколько руководств (см. Здесь , здесь и здесь ), но у них не было полного объяснения с результатами, которые я искал.
Я добавляю этот ответ типа Q & A, чтобы помочь себе узнать, как использовать BreakIterator
.
- RecyclerView - просмотр в определенном положении
- Как программно удалить файлы на Android?
- Recyclerview мучительно медленно загружает кешированные изображения из Picasso
- завершение программы на выходе основного streamа?
- Ковариация, инвариантность и контравариантность объясняются на простом английском языке?
Я делаю это тегом Android в дополнение к Java, потому что, по- видимому, существует разница между ними. Кроме того, Android теперь поддерживает BreakIterator
и в будущем ответы могут быть BreakIterator
.
- Android для выбора цвета для включения в активность
- в чем разница между i ++ и ++ i in for loop (Java)?
- Что такое хорошая библиотека для анализа математических выражений в java?
- Реализация паузы / возобновления загрузки файла
- Преобразование долготы / широты в координату X / Y
- $ 0 (название программы) в Java? Откройте для себя основной class?
- Настройка spinner onClickListener () в Android
- java.util.ConcurrentModificationException при добавлении другого объекта
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
для onCreate
на Android. Я использую 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 。
Здесь есть несколько интересных вещей. Во-первых, разрыв слов обнаруживается с обеих сторон пространства. Во-вторых, несмотря на то, что существуют разные языки, все еще признавались многосимвольные китайские слова. Это было по-прежнему справедливо в моих тестах, даже когда я установил локаль в Locale.US
.
линии
Вы можете сохранить код таким же, как для примера Words:
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();
Вывод
0 I like to eat apples. 22 My email is [email protected] 50 This is a new paragraph. 75 我喜欢吃苹果。 82 我不爱吃臭豆腐。
Правильные разрывы предложений были распознаны на нескольких языках. Кроме того, не было ложного позитива для точки в домене электронной почты.
Заметки
Вы можете установить Locale при создании BreakIterator
, но если вы этого не сделаете, он просто использует локаль по умолчанию .
дальнейшее чтение
- Документация
- Версия ICU для BreakIterator
- Это был один из самых полезных уроков.