141 votes

Fractionner une chaîne pour obtenir des sous-chaînes de longueur égale en Java

Comment diviser la chaîne "Thequickbrownfoxjumps" en sous-chaînes de taille égale en Java. Par exemple. "Thequickbrownfoxjumps" de 4 tailles égales devraient donner la sortie.

 ["Theq","uick","brow","nfox","jump","s"]
 

Question similaire:

Fractionner la chaîne en sous-chaînes de même longueur dans Scala

262voto

Alan Moore Points 39365

Voici la regex one-liner version:

System.out.println(Arrays.toString(
    "Thequickbrownfoxjumps".split("(?<=\\G.{4})")
));

\G est un zéro-largeur affirmation qui correspond à la position où le précédent match s'est terminé. Si il n'y a pas de match précédent, il correspond au début de l'entrée, le même que l' \A. La enfermant lookbehind correspond à la position que les quatre personnages de la fin du dernier match.

Les deux lookbehind et \G sont à un stade avancé de la regex de fonctionnalités, non pris en charge par toutes les saveurs. En outre, \G n'est pas mis en œuvre de manière cohérente à travers les saveurs qui ne le soutien. Cette astuce fonctionne (par exemple) en Java, Perl, .NET et JGSoft, mais pas en PHP (PCRE), Ruby 1.9+ ou TextMate (les deux Oniguruma).

EDIT: je tiens à préciser que je n'ai pas forcément recommander cette solution si vous avez d'autres options. Le non-regex solutions dans les autres réponses peuvent être plus longue, mais ils sont aussi l'auto-documentation; celui-ci est à peu près le contraire de cela. ;)

152voto

Jon Skeet Points 692016

Eh bien, il est assez facile de le faire par la force brute:

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

Je ne pense pas que cela vaut vraiment le coup, à l'aide d'une regex pour cela.

EDIT: Mon raisonnement pour ne pas utiliser une regex:

  • Ce n'utilise pas du tout de la véritable correspondance de motif de regexes. C'est juste de comptage.
  • Je soupçonne la ci-dessus sera plus efficace, bien que dans la plupart des cas, il ne sera pas question
  • Si vous avez besoin d'utiliser des dimensions variables dans des endroits différents, vous avez eu la répétition ou une fonction d'aide à construire la regex lui-même basé sur un paramètre - ick.
  • L'expression régulière fournie dans une autre réponse tout d'abord de ne pas compiler (non valide s'échapper), et ensuite n'a pas de travail. Mon code a travaillé la première fois. C'est plus un témoignage de la facilité d'utilisation de regexes vs code clair, de l'OMI.

78voto

Sean Patrick Floyd Points 109428

C'est très facile avec Google Goyave:

for(final String token :
    Splitter
        .fixedLength(4)
        .split("Thequickbrownfoxjumps")){
    System.out.println(token);
}

Sortie:

Theq
uick
brow
nfox
jump
s

Ou si vous avez besoin du résultat dans un tableau, vous pouvez utiliser ce code:

String[] tokens =
    Iterables.toArray(
        Splitter
            .fixedLength(4)
            .split("Thequickbrownfoxjumps"),
        String.class
    );

Référence:

J'ai joué avec l'idée de créer une regex version aussi, mais je ne pouvais pas venir avec un one-liner pour la Chaîne.split(). Et j'ai supprimé mes précédentes tentatives, parce que le problème a été résolu par Alan Moore. Mais je suis d'accord avec les autres que la regex n'est pas le bon outil pour cela (même si cela fonctionne).

TL;DR:

Trois options:

15voto

Cowan Points 17235

Si vous utilisez les bibliothèques générales de Google goyaves de Google (et tout à fait honnêtement, tout nouveau projet Java devrait l' être), la classe Splitter est extrêmement triviale:

 for (String substring : Splitter.fixedLength(4).split(inputString)) {
    doSomethingWith(substring);
}
 

et c'est tout . Facile comme!

8voto

Saul Points 10449
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;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X