
emilio
Cómo dividir la cadena "Thequickbrownfoxjumps"
a subcadenas de igual tamaño en Java. P.ej. "Thequickbrownfoxjumps"
de 4 de igual tamaño debe dar la salida.
["Theq","uick","brow","nfox","jump","s"]
Pregunta similar:
Dividir cadena en subcadenas de igual longitud en Scala

alan moore
Aquí está la versión de una sola línea de expresiones regulares:
System.out.println(Arrays.toString(
"Thequickbrownfoxjumps".split("(?<=\\G.{4})")
));
\G
es una aserción de ancho cero que coincide con la posición donde terminó la coincidencia anterior. Sí hay era ninguna coincidencia anterior, coincide con el comienzo de la entrada, lo mismo que \A
. El lookbehind adjunto coincide con la posición que está a cuatro caracteres del final de la última coincidencia.
Ambos miran atrás y \G
son características avanzadas de expresiones regulares, no compatibles con todos los sabores. Es más, \G
no se implementa de manera consistente en todos los sabores que lo admiten. Este truco funcionará (por ejemplo) en JavaPerl, .NET y JGSoft, pero no en PHP (PCRE), Ruby 1.9+ o TextMate (ambos Oniguruma). JavaScript /y
(bandera adhesiva) no es tan flexible como \G
y no podría usarse de esta manera incluso si JS admitiera mirar atrás.
Debo mencionar que no necesariamente recomendar esta solución si tiene otras opciones. Las soluciones que no son expresiones regulares en las otras respuestas pueden ser más largas, pero también se autodocumentan; este es casi el opuesto de eso. 😉
Además, esto no funciona en Android, que no admite el uso de \G
en mirar atrás.

jon skeet
Bueno, es bastante fácil hacer esto con operaciones aritméticas y de cadenas simples:
public static List<String> splitEqually(String text, int size) {
// Give the list the right capacity to start with. You could use an array
// instead if you wanted.
List<String> ret = new ArrayList<String>((text.length() + size - 1) / size);
for (int start = 0; start < text.length(); start += size) {
ret.add(text.substring(start, Math.min(text.length(), start + size)));
}
return ret;
}
Nota: esto supone un mapeo 1:1 de la unidad de código UTF-16 (char
, efectivamente) con “carácter”. Esa suposición se rompe para los caracteres fuera del plano multilingüe básico, como los emoji y (dependiendo de cómo quieras contar las cosas) la combinación de caracteres.
No creo que realmente valga la pena usar una expresión regular para esto.
EDITAR: Mi razonamiento para no usar una expresión regular:
- Esto no utiliza ninguna de las coincidencias de patrones reales de expresiones regulares. Solo está contando.
- I sospechar lo anterior será más eficiente, aunque en la mayoría de los casos no importará
- Si necesita usar tamaños variables en diferentes lugares, tiene repetición o una función de ayuda para construir la expresión regular en sí misma en función de un parámetro, ick.
- La expresión regular proporcionada en otra respuesta primero no se compiló (escape no válido) y luego no funcionó. Mi código funcionó a la primera. Eso es más un testimonio de la usabilidad de las expresiones regulares frente al código simple, en mi opinión.

sean patrick floyd
Esto es muy fácil con Google guayaba:
for(final String token :
Splitter
.fixedLength(4)
.split("Thequickbrownfoxjumps")){
System.out.println(token);
}
Producción:
Theq
uick
brow
nfox
jump
s
O si necesita el resultado como una matriz, puede usar este código:
String[] tokens =
Iterables.toArray(
Splitter
.fixedLength(4)
.split("Thequickbrownfoxjumps"),
String.class
);
Referencia:
Nota: la construcción de divisores se muestra en línea arriba, pero dado que los divisores son inmutables y reutilizables, es una buena práctica almacenarlos en constantes:
private static final Splitter FOUR_LETTERS = Splitter.fixedLength(4);
// more code
for(final String token : FOUR_LETTERS.split("Thequickbrownfoxjumps")){
System.out.println(token);
}
Si está utilizando Google guayaba bibliotecas de uso general (y, sinceramente, cualquier nuevo proyecto de Java probablemente deberían ser), esto es increíblemente trivial con el Disidente clase:
for (String substring : Splitter.fixedLength(4).split(inputString)) {
doSomethingWith(substring);
}
y eso es eso. Fácil como!

Saúl
public static String[] split(String src, int len) {
String[] result = new String[(int)Math.ceil((double)src.length()/(double)len)];
for (int i=0; i<result.length; i++)
result[i] = src.substring(i*len, Math.min(src.length(), (i+1)*len));
return result;
}

Grodríguez
public String[] splitInParts(String s, int partLength)
{
int len = s.length();
// Number of parts
int nparts = (len + partLength - 1) / partLength;
String parts[] = new String[nparts];
// Break into parts
int offset= 0;
int i = 0;
while (i < nparts)
{
parts[i] = s.substring(offset, Math.min(offset + partLength, len));
offset += partLength;
i++;
}
return parts;
}
Aquí está un un trazador de líneas versión que utiliza Java 8 IntStream para determinar los índices de los inicios de corte:
String x = "Thequickbrownfoxjumps";
String[] result = IntStream
.iterate(0, i -> i + 4)
.limit((int) Math.ceil(x.length() / 4.0))
.mapToObj(i ->
x.substring(i, Math.min(i + 4, x.length())
)
.toArray(String[]::new);
¿Qué intentaste? ¿Por qué no funcionó?
– Thilo
21 de septiembre de 2010 a las 12:18
¿Necesitas usar una expresión regular para esto? Solo pregunto por la etiqueta regex …
–Tim Pietzcker
21 de septiembre de 2010 a las 12:19
El enlace de @Thilo que publicó es para Scala, está preguntando sobre lo mismo en Java
– Jaydeep Patel
21 de septiembre de 2010 a las 12:20
@Thilo: Estaba preguntando cómo hacerlo en Java, como la respuesta dada para Scala.
– Emilio
21 de septiembre de 2010 a las 12:27