java - ¿Cómo funciona BreakIterator en Android?
word-wrap (1)
Estoy haciendo mi propio procesador de texto en Android (un script vertical personalizado TextView para mongol).
Pensé que tendría que encontrar todas las ubicaciones de
BreakIterator
línea para poder implementar el
BreakIterator
línea, pero luego descubrí
BreakIterator
.
Esto parece encontrar todos los saltos posibles entre caracteres, palabras, líneas y oraciones en varios idiomas.
Estoy tratando de aprender cómo usarlo. La BreakIterator fue más útil que el promedio, pero aún así fue difícil de entender simplemente leyendo. También encontré algunos tutoriales (ver here , here y here ) pero carecían de la explicación completa con la salida que estaba buscando.
Estoy agregando esta respuesta de estilo de preguntas y respuestas para ayudarme a aprender cómo usar
BreakIterator
.
Estoy haciendo de esto una etiqueta de Android además de Java porque
aparentemente hay alguna diferencia
entre ellos.
Además, Android ahora es compatible con el
ICU
BreakIterator
y las futuras respuestas pueden abordar esto.
BreakIterator
se puede utilizar para encontrar los posibles saltos entre caracteres, palabras, líneas y oraciones.
Esto es útil para cosas como mover el cursor a través de caracteres visibles, hacer doble clic para seleccionar palabras, hacer triple clic para seleccionar oraciones y ajustar líneas.
Código repetitivo
El siguiente código se utiliza en los ejemplos a continuación.
Simplemente ajuste la primera parte para cambiar el texto y el tipo de
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;
}
Si solo quiere probar esto, puede pegarlo directamente en una actividad
onCreate
en Android.
Estoy usando
System.out.println
lugar de
Log
para que también sea comprobable en un entorno solo de Java.
Estoy usando el
java.text.BreakIterator
lugar del ICU, que solo está disponible desde la API 24. Consulte los enlaces en la parte inferior para obtener más información.
Caracteres
Cambie el código repetitivo para incluir lo siguiente
String text = "Hi 中文éé/uD83D/uDE00/uD83C/uDDEE/uD83C/uDDF3.";
BreakIterator breakIterator = BreakIterator.getCharacterInstance();
Salida
0 H
1 i
2
3 中
4 文
5 é
6 é
8 😀
10 🇮🇳
14 .
Las partes más interesantes están en los índices
6
,
8
y
10
.
Es posible que su navegador muestre o no los caracteres correctamente, pero un usuario interpretaría que todos estos son caracteres individuales a pesar de que están formados por múltiples valores UTF-16.
Palabras
Cambie el código repetitivo para incluir lo siguiente:
String text = "I like to eat apples. 我喜欢吃苹果。";
BreakIterator boundary = BreakIterator.getWordInstance();
Salida
0 I
1
2 like
6
7 to
9
10 eat
13
14 apples
20 .
21
22 我
23 喜欢
25 吃
26 苹果
28 。
Hay algunas cosas interesantes para tener en cuenta aquí.
Primero, se detecta un salto de palabra a ambos lados de un espacio.
En segundo lugar, a pesar de que existen diferentes idiomas, aún se reconocieron las palabras chinas de varios caracteres.
Esto todavía era cierto en mis pruebas incluso cuando configuré la configuración regional en
Locale.US
.
Líneas
Puede mantener el código igual que para el ejemplo de palabras:
String text = "I like to eat apples. 我喜欢吃苹果。";
BreakIterator boundary = BreakIterator.getLineInstance();
Salida
0 I
2 like
7 to
10 eat
14 apples.
22 我
23 喜
24 欢
25 吃
26 苹
27 果。
Tenga en cuenta que las ubicaciones de ruptura no son líneas completas de texto. Son solo lugares convenientes para el texto de ajuste de línea.
El resultado es similar al ejemplo de palabras. Sin embargo, ahora el espacio en blanco y la puntuación se incluyen con la palabra anterior. Esto tiene sentido porque no desea que una nueva línea comience con espacios en blanco o signos de puntuación. También tenga en cuenta que los caracteres chinos obtienen saltos de línea para cada carácter. Esto es consistente con el hecho de que está bien dividir palabras de varios caracteres entre líneas en chino.
Frases
Cambie el código repetitivo para incluir lo siguiente:
String text = "I like to eat apples. My email is [email protected]./n" +
"This is a new paragraph. 我喜欢吃苹果。我不爱吃臭豆腐。";
BreakIterator boundary = BreakIterator.getSentenceInstance();
Salida
0 I like to eat apples.
22 My email is [email protected].
50 This is a new paragraph.
75 我喜欢吃苹果。
82 我不爱吃臭豆腐。
Los saltos de oración correctos se reconocieron en varios idiomas. Además, no hubo falsos positivos para el punto en el dominio de correo electrónico.
Notas
Puede establecer la configuración
Locale
cuando crea un
BreakIterator
, pero si no lo hace, solo usa la
configuración regional predeterminada
.
Otras lecturas
- BreakIterator
- Versión de ICU de BreakIterator
- here fue uno de los tutoriales más útiles.