web-dev-qa-db-fra.com

Fractionner une chaîne à chaque nième caractère

En JavaScript, c'est ainsi que nous pouvons diviser une chaîne à chaque 3ème caractère

"foobarspam".match(/.{1,3}/g)

J'essaie de comprendre comment faire cela en Java. Des pointeurs?

68
Vijay Dev

Vous pouvez le faire comme ceci:

String s = "1234567890";
System.out.println(Java.util.Arrays.toString(s.split("(?<=\\G...)")));

qui produit:

[123, 456, 789, 0]

Le regex (?<=\G...) correspond à une chaîne vide qui a le dernière correspondance (\G) suivi de trois caractères (...) avant it ((?<= ))

117
Bart Kiers

Java ne fournit pas d'utilitaires de fractionnement très complets, donc les bibliothèques de goyave font:

Iterable<String> pieces = Splitter.fixedLength(3).split(string);

Découvrez le Javadoc pour Splitter ; c'est très puissant.

81
Kevin Bourrillion
import Java.util.ArrayList;
import Java.util.List;

public class Test {
    public static void main(String[] args) {
        for (String part : getParts("foobarspam", 3)) {
            System.out.println(part);
        }
    }
    private static List<String> getParts(String string, int partitionSize) {
        List<String> parts = new ArrayList<String>();
        int len = string.length();
        for (int i=0; i<len; i+=partitionSize)
        {
            parts.add(string.substring(i, Math.min(len, i + partitionSize)));
        }
        return parts;
    }
}
46
Simon Nickerson

En complément de Bart Kiers réponse, je veux ajouter que c'est possible au lieu d'utiliser les trois points ... dans l'expression d'expression régulière qui représentent trois caractères, vous pouvez écrire .{3} qui a la même signification.

Ensuite, le code ressemblerait à ceci:

String bitstream = "00101010001001010100101010100101010101001010100001010101010010101";
System.out.println(Java.util.Arrays.toString(bitstream.split("(?<=\\G.{3})")));

Avec cela, il serait plus facile de modifier la longueur de chaîne et la création d'une fonction est maintenant raisonnable avec une longueur de chaîne d'entrée variable. Cela pourrait se faire comme suit:

public static String[] splitAfterNChars(String input, int splitLen){
    return input.split(String.format("(?<=\\G.{%1$d})", splitLen));
}

Un exemple dans IdeOne: http://ideone.com/rNlTj5

4
Frodo

Entrée tardive.

Voici une implémentation succincte utilisant des flux Java8, une ligne:

String foobarspam = "foobarspam";
AtomicInteger splitCounter = new AtomicInteger(0);
Collection<String> splittedStrings = foobarspam
                                    .chars()
                                    .mapToObj(_char -> String.valueOf((char)_char))
                                    .collect(Collectors.groupingBy(stringChar -> splitCounter.getAndIncrement() / 3
                                                                ,Collectors.joining()))
                                    .values();

Sortie:

[foo, bar, spa, m]
3
Pankaj Singhal

C'est une réponse tardive, mais je la mets quand même à la disposition des nouveaux programmeurs:

Si vous ne souhaitez pas utiliser d'expressions régulières, et ne souhaitez pas compter sur une bibliothèque tierce, vous pouvez utiliser cette méthode à la place, qui prend entre 8992 et 10011 nanosecondes dans un processeur 2,80 GHz (moins d'une milliseconde). Ce n'est pas aussi joli que l'exemple de Simon Nickerson, mais cela fonctionne:

   /**
     * Divides the given string into substrings each consisting of the provided
     * length(s).
     * 
     * @param string
     *            the string to split.
     * @param defaultLength
     *            the default length used for any extra substrings. If set to
     *            <code>0</code>, the last substring will start at the sum of
     *            <code>lengths</code> and end at the end of <code>string</code>.
     * @param lengths
     *            the lengths of each substring in order. If any substring is not
     *            provided a length, it will use <code>defaultLength</code>.
     * @return the array of strings computed by splitting this string into the given
     *         substring lengths.
     */
    public static String[] divideString(String string, int defaultLength, int... lengths) {
        Java.util.ArrayList<String> parts = new Java.util.ArrayList<String>();

        if (lengths.length == 0) {
            parts.add(string.substring(0, defaultLength));
            string = string.substring(defaultLength);
            while (string.length() > 0) {
                if (string.length() < defaultLength) {
                    parts.add(string);
                    break;
                }
                parts.add(string.substring(0, defaultLength));
                string = string.substring(defaultLength);
            }
        } else {
            for (int i = 0, temp; i < lengths.length; i++) {
                temp = lengths[i];
                if (string.length() < temp) {
                    parts.add(string);
                    break;
                }
                parts.add(string.substring(0, temp));
                string = string.substring(temp);
            }
            while (string.length() > 0) {
                if (string.length() < defaultLength || defaultLength <= 0) {
                    parts.add(string);
                    break;
                }
                parts.add(string.substring(0, defaultLength));
                string = string.substring(defaultLength);
            }
        }

        return parts.toArray(new String[parts.size()]);
    }
1
Cardinal System

Vous pouvez également diviser une chaîne à chaque n-ième caractère et les placer chacun, dans chaque index d'une liste:

Ici, j'ai fait une liste de chaînes nommées Sequence:

Liste <séquence> séquence

Ensuite, je divise essentiellement la chaîne "KILOSO" par tous les 2 mots. Ainsi, 'KI' 'LO' 'SO' serait incorporé dans un index séparé de la liste appelé séquence.

Chaîne S = KILOSO

Sequence = Arrays.asList (S.split ("(? <=\G ..)"));

Alors quand je fais:

System.out.print (séquence)

Il devrait imprimer:

[KI, LO, SO]

pour vérifier que je peux écrire:

System.out.print (Sequence.get (1))

il imprimera:

LO

0
Victor Truong