简体   繁体   中英

Split a string at every 4-th character?

I have a string which i have to split into substrings of equal length if possible. I have found this solution which will only work if the string length is a multiple of 4.

String   myString = "abcdefghijklm";
String[] split = myString.split("(?<=\\G....)");

This will produce:

[abcd, efgh, ijkl, m]

What i need is to split "from the end of the string". My desired output should look like :

[a, bcde, fghi, jklm]

How do i achieve this?

This ought to do it:

String[] split = myString.split("(?=(....)+$)");
// or
String[] split = myString.split("(?=(.{4})+$)");

What it does is this: split on the empty string only if that empty string has a multiple of 4 chars ahead of it until the end-of-input is reached.

Of course, this has a bad runtime (O(n^2)). You can get a linear running time algorithm by simply splitting it yourself.

As mentioned by @anubhava:

(?!^)(?=(?:.{4})+$) to avoid empty results if string length is in multiples of 4

Regex are really unnecessary for this. I also don't think this is a good problem for recursion. The following is an O(n) solution.

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

No need to use a regular expression. Instead, you can recursively build a list of head strings and return the tail.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM