1

This code totally runs when I am applying it outside android, that is, in a pure java enviroment. (There is a link that says it is a doublicate of the question, but its not) I want to know why it runs in java without android, but crashes in android.

String[] ar = new String[iters];
ar = myStr.split("(?<=\\G.{16})");

However, when I apply the same in android enviroment, I get the following exception

04-13 13:50:22.255: E/AndroidRuntime(2147): FATAL EXCEPTION: main
04-13 13:50:22.255: E/AndroidRuntime(2147): java.util.regex.PatternSyntaxException: Look-behind pattern matches must have a bounded maximum length near index 12:
04-13 13:50:22.255: E/AndroidRuntime(2147): (?<=\G.{16})
4
  • 1
    Avoid (?<=\\G.whatever) approach. Even if it works in standard Java, it does it against regex engine assumptions that look-behind needs to have maximal length and we don't know what length \\G represents. So as you see this behaviour can change in newer versions of Java (or Java-like environments like Android). Instead use Pattern and Matcher classes like Matcher m = Pattern.compile(".{16}").matcher(myStr); while (m.find){ String s = m.group(); ... } Commented Apr 13, 2015 at 11:12
  • @Pshemo can you provide a working example for the above using those? Commented Apr 13, 2015 at 11:16
  • OK, I posted answer with example of how you can rewrite your code using Pattern and Matcher classes. I didn't add code responsible for storing each token in array since I don't know if you will need it really because you may already handle each token returned by m.group() as you want (in my code I print it, but you can store it in some List like ArrayList and reuse later). Commented Apr 13, 2015 at 11:29
  • @Pshemo thanks a lot. indeed. no need for arrays as I can use them directly (which I'm doing) thanks Commented Apr 13, 2015 at 15:16

1 Answer 1

5

Possible reason:

It looks like a bug of Java version which your Android is using, which was corrected in later Java versions.

\G can be considered as anchor which represents either

  • end of previous match
  • start of the string (if no match was found yet)

and as any anchor it is zero-length.

I suspect that main part of that bug is that \G is seen by look-behind as entire previous match, not its end, and since previous match could have any length look-behind complains about it because it can't determine obvious maximal length.

Way around.

Avoid split("(?<=\\Gwhatever)").

Instead of finding delimiters, use Matcher class to find() things you want to get from text. So your code can look like:

String myStr = "0123456789012345678901234567890123456789012345678901234567890123456789";

Matcher m = Pattern.compile(".{1,16}").matcher(myStr);
while (m.find()) {
    String s = m.group();
    //do what you want with current token stored in `s`
    System.out.println(s);
}

Output:

0123456789012345
6789012345678901
2345678901234567
8901234567890123
456789
Sign up to request clarification or add additional context in comments.

2 Comments

Good solution, but I disagree with your analysis. \G is a zero-width assertion; it matches the position where the previous match ended. It doesn't consume any characters, so it can't affect the length of what's matched inside the lookbehind. \G in lookbehinds has always worked in Java, and it should work in Android.
@AlanMoore I also though that it should work in a way you mention, but I remember having problem which made me little skeptic about it. I don't remember in which Java version was it precisely nor how regex looked like, but there was case where I had (?<=something) and it worked fine, but adding \G like (?<=\Gsomething) caused Look-behind group does not have an obvious maximum length... problem. So since something part had obvious maximal length it looked like \G may be seen as non-zero-width.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.