Cadena dividida en subcadenas de igual longitud en Java

2 minutos de lectura

Cadena dividida en subcadenas de igual longitud en Java
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

  • ¿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

Cadena dividida en subcadenas de igual longitud en Java
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 \Gy 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.

  • En PHP 5.2.4 funciona el siguiente código: return preg_split(‘/(?<=\G. {'.$len.'})/u', $str,-1,PREG_SPLIT_NO_EMPTY);

    – Igor

    23 de marzo de 2012 a las 14:50


  • Para el registro, utilizando String.substring() en lugar de una expresión regular, aunque requiere algunas líneas adicionales de código, se ejecutará en algún lugar del orden de 5 veces más rápido…

    – dibujó moore

    23 de septiembre de 2014 a las 14:17

  • En Java esto no funciona para una cadena con saltos de línea. Solo verificará hasta la primera línea nueva, y si esa línea nueva está antes del tamaño dividido, entonces la cadena no se dividirá. ¿O me he perdido algo?

    – joensson

    11 de noviembre de 2014 a las 22:58

  • En aras de la exhaustividad: la división de texto en varias líneas necesita un prefijo (?s) en la expresión regular: (?s)(?<=\\G.{4}).

    – bobbel

    29 de marzo de 2016 a las 10:26

  • @JeffreyBlattman Dudo que hayas obtenido la excepción en tiempo de compilación

    – Holger

    20 de septiembre de 2019 a las 12:49

1646745251 550 Cadena dividida en subcadenas de igual longitud en Java
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.

  • @Emil: En realidad, tú no lo hizo pedir una expresión regular. Está en las etiquetas, pero nada en la pregunta en sí pide una expresión regular. Pones este método en un solo lugar, y luego puedes dividir la cadena en solo uno muy legible declaración en cualquier parte de su código.

    – Jon Skeet

    21 de septiembre de 2010 a las 12:31

  • Emil, esto no es para lo que sirve una expresión regular. Período.

    – Chris

    21 de septiembre de 2010 a las 12:43

  • @Emil: si quieres una sola línea para dividir la cadena, te recomiendo Guava’s Splitter.fixedLength(4) como sugiere seanizer.

    – ColinD

    21 de septiembre de 2010 a las 13:43


  • @ Jay: vamos, no es necesario que seas tan sarcástico. Estoy seguro de que se puede hacer usando expresiones regulares en una sola línea. Una subcadena de longitud fija también es un patrón. ¿Qué dices sobre esta respuesta? stackoverflow.com/questions/3760152/… .

    – Emilio

    21 de septiembre de 2010 a las 15:16


  • @Emil: No pretendía que fuera grosero, solo caprichoso. La parte seria de mi punto fue que si bien sí, estoy seguro de que podría crear un Regex para hacer esto, veo que Alan Moore tiene uno que dice que funciona, es críptico y, por lo tanto, difícil para un programador posterior. comprender y mantener. Una solución de subcadena puede ser intuitiva y legible. Vea la cuarta viñeta de Jon Skeet: Estoy de acuerdo con eso al 100%.

    – Jay

    21 de septiembre de 2010 a las 18:53

Cadena dividida en subcadenas de igual longitud en Java
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);
}

  • Gracias por la publicación (por informarme sobre el método de la biblioteca de guayaba). Pero tendré que aceptar la respuesta de expresiones regulares stackoverflow.com/questions/3760152/… ya que no requiere ninguna biblioteca de terceros ni una sola línea.

    – Emilio

    21 de septiembre de 2010 a las 15:31


  • Incluir cientos de KB de código de biblioteca solo para realizar esta simple tarea es casi seguro que no es lo correcto.

    –Jeffrey Blattman

    4 mayo 2016 a las 22:46

  • @JeffreyBlattman, incluir a Guayaba solo por esto probablemente sea excesivo, cierto. Pero lo uso como una biblioteca de propósito general en todo mi código Java de todos modos, entonces, ¿por qué no usar esta funcionalidad adicional?

    – Sean Patrick Floyd

    26 de enero de 2017 a las 14:38

  • alguna forma de volver a unir con un separador?

    – Poder de Acuario

    2 de mayo de 2017 a las 5:49

  • @AcuarioPoder String.join(separator, arrayOrCollection)

    – Holger

    20 de septiembre de 2019 a las 12:58

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!

1646745252 874 Cadena dividida en subcadenas de igual longitud en Java
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;
}

  • Ya que src.length() y len son ambos ints, tu llamada ceiling no está consiguiendo lo que quieres; mira cómo lo están haciendo algunas de las otras respuestas: (src.length() + len – 1) / len

    – Michael Brewer-Davis

    21 de septiembre de 2010 a las 13:24

  • @Michael: Buen punto. No lo probé con cadenas de longitudes no múltiples. Está arreglado ahora.

    – Saulo

    21 de septiembre de 2010 a las 13:50

1646745253 294 Cadena dividida en subcadenas de igual longitud en Java
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;
}

  • Ya que src.length() y len son ambos ints, tu llamada ceiling no está consiguiendo lo que quieres; mira cómo lo están haciendo algunas de las otras respuestas: (src.length() + len – 1) / len

    – Michael Brewer-Davis

    21 de septiembre de 2010 a las 13:24

  • @Michael: Buen punto. No lo probé con cadenas de longitudes no múltiples. Está arreglado ahora.

    – Saulo

    21 de septiembre de 2010 a las 13:50

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

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad