J'ai une chaîne que je dois diviser en sous-chaînes de longueur égale si possible. J'ai trouvé cette solution qui ne fonctionnera que si la longueur de la chaîne est un multiple de 4.
[a, bcde, fghi, jklm]
Cela produira:
[abcd, efgh, ijkl, m]
Quoi j'ai besoin est de diviser "de la fin de la chaîne". Le résultat souhaité doit ressembler à:
String myString = "abcdefghijklm"; String[] split = myString.split("(?<=\\G....)");
Comment puis-je y parvenir?
3 Réponses :
Cela devrait le faire:
String[] split = myString.split("(?=(....)+$)"); // or String[] split = myString.split("(?=(.{4})+$)");
Ce qu'il fait est ceci: diviser sur la chaîne vide uniquement si cette chaîne vide a un multiple de 4 caractères devant elle jusqu'à la fin de -input est atteint.
Bien sûr, cela a un mauvais runtime (O (n ^ 2)). Vous pouvez obtenir un algorithme de temps d'exécution linéaire en le divisant simplement vous-même.
Comme mentionné par @anubhava:
(?! ^) (? = (?:. {4}) + $)
pour éviter les résultats vides si la longueur de la chaîne est en multiples de 4
A tenté. Rend [a, bcde, fghi, jklm]
comme demandé.
Merci beaucoup. Travaux.
(?! ^) (? = (?:. {4}) + $)
pour éviter un résultat vide si la longueur de la chaîne est en multiples de 4
Merci à tous pour les améliorations et les explications.
Pas besoin d'utiliser une expression régulière. Au lieu de cela, vous pouvez créer récursivement une liste de chaînes d'en-tête et renvoyer la queue.
import java.util.*; public class StringChunker { public static void main(String[] args) { String str = "abcdefghijklm"; System.out.println(Arrays.toString(chunk(str, 4))); // [abcd, efgh, ijkl, m] System.out.println(Arrays.toString(chunk(str, 4, true))); // [a, bcde, fghi, jklm] } public static String[] chunk(String str, int size) throws IllegalArgumentException { return chunk(str, size, false); } public static String[] chunk(String str, int size, boolean reverse) throws IllegalArgumentException { return chunk(str, size, reverse, new ArrayList<String>()); } private static String[] chunk(String str, int size, boolean reverse, List<String> chunks) throws IllegalArgumentException { if (size < 1) { throw new IllegalArgumentException("size must be greater than 0"); } if (str.length() < size) { if (reverse) { chunks.add(0, str); // Reverse adds to the front of the list } else { chunks.add(str); // Add to the end of the list } return chunks.toArray(new String[chunks.size()]); // Convert to an array } else { String head, tail; if (reverse) { head = str.substring(str.length() - size, str.length()); tail = str.substring(0, str.length() - size); chunks.add(0, head); } else { head = str.substring(0, size); tail = str.substring(size); chunks.add(head); } return chunk(tail, size, reverse, chunks); } } }
Les expressions régulières ne sont vraiment pas nécessaires pour cela. Je ne pense pas non plus que ce soit un bon problème pour la récursivité. Voici une solution O (n).
public static String[] splitIt(String input, int splitLength){ int inputLength = input.length(); ArrayList<String> arrayList = new ArrayList<>(); int i = inputLength; while(i > 0){ int beginIndex = i - splitLength > 0 ? i - splitLength : 0; arrayList.add(0, input.substring(beginIndex, i)); i -= splitLength; } return arrayList.toArray(new String[0]); }
Copie possible de Fractionnement d'une chaîne à chaque n-ième caractère
@Ruslan Ce n'est pas une copie de la question liée. Veuillez regarder ma sortie souhaitée.
Cela devrait être fait sans regex dans une simple boucle.