views:

500

answers:

3

In JavaScript this is how we can split a string at every 3-rd character

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

I am trying to figure out how to do this in Java. Any pointers?

+5  A: 
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;
    }
}
Simon Nickerson
+1 for choosing the simplest way to solve the problem.
Vijay Dev
keep in mind that 'substring' will create len/partitionSize copies of the original string. So use 'new String(string.substring(...))' to avoid using extra memory.
tulskiy
If you keep a collection of substrings that cover the entire original string, the new String method will actually waste (n-1)*sizeof(int). The new Strings' char arrays will take the same memory, but each one will have a separate length field. That said, if any substrings are later discarded, new String could reduce memory. I wouldn't worry either way unless the original string is very big.
ILMTitan
+6  A: 

You could do it like this:

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

which produces:

[123, 456, 789, 0]

The regex (?<=\G...) matches an empty string that has the last match (\G) followed by three characters (...) before it ((?<= ))

Bart Kiers
Brrr... scary :) Java's regex flavor is a bit alien to me.
Vinko Vrsalovic
:) I'd probably go for Simon's solution as well: my co-workers might not like it if I start adding my regex-trickery to the code base.
Bart Kiers
Yeah, it's definitely scary. Scary, but brilliant! +1.
Vijay Dev
I'd hate to think someone voted this answer down simply because they don't like regular expressions.
William Brendel
I would stick to your's and Kenny's advices and go with a non-regex solution. Thanks for the help!
Vijay Dev
No problem, and (probably) a wise decision.
Bart Kiers
mad props for supreme regex mojo, but as a reader of this code, I'd hunt you down and egg your house. :)
Kevin Bourrillion
As long as you call this via a correctly named function (ie splitIntoParts) and don't directly embed that line in your code, it's all good. Otherwise, let the hunting begin :)
GreenieMeanie
Part of what makes this trick so scary is that it won't work in all languages. For example, JavaScript doesn't support `\G`, and Python won't split on a regex that matches zero characters. But then, if Java had a "get all matches" method like every other language does, you wouldn't have had to invent this trick in the first place, @Bart. ;)
Alan Moore
+9  A: 

Java does not provide very full-featured splitting utilities, so the Guava libraries do:

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

Check out the javadoc for Splitter; it's very powerful.

Kevin Bourrillion
+1 This is the correct answer (also known as: *know and use the libraries*)
Jonik
I would take this answer over the regex...just because it's more maintainable (e.g. the fact that less people know about RegEx than ppl being able to read "readable" code.)
ShaChris23