2

The regular expression, specifically for negative lookahead patterns, does not seem to work properly in Android 2.1 code.

See example below:

private String parseString(String regex, String raw) {
    StringBuffer sb = new StringBuffer();
    Matcher m = Pattern.compile(regex).matcher(raw);
    m.matches();
    if (m.find()) sb.append(m.group()); 
    return sb.toString();
}

// Using the helper method above:
// Looking for 4-digit numeric strings within a text
String regex = "(\\d{4})(?!\\d)";
String text = "Looking for a 4-digit string 1234 in here!";
Log.i("Test", "[" + parseString(regex, text) + "]");

On Android 2.1, the result comes as:

I/Test (  451): []

On Android 2.2, it is:

I/Test (  451): [1234]

Does anyone know the reason for this?

bruno.braga
  • 1,001
  • 12
  • 21
  • Before anyone asks, the negative pattern is used to ensure that \d{4} does not catch strings like "123456", returning "1234". – bruno.braga Feb 15 '13 at 06:47
  • Off-topic but... If you are interested only in the first result why do you need `while` loop? `m.find(); sb.append(m.group());` should be enough. – Leri Feb 15 '13 at 06:50
  • @bruno.braga: Sharing your research is great and encouraged on SO. But SO is a Questions and Answer site, so the accepted way of sharing ones research is to ask the question that lead to the research and answer it directly with the research result. See [here](http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/) for more info. – Daniel Hilgarth Feb 15 '13 at 06:52
  • And now about stackoverflow. it is QA site so your _question_ does not fit, because, in fact, there is not any question here. You should divide your post into to part: `1. Issue and post it as a question. 2. Solution and post it as an answer.` – Leri Feb 15 '13 at 06:52
  • @Bruno, I have tested in Andorid 2.1 emulator just now. It gives correct answer. – Sunil Kumar Sahoo Feb 15 '13 at 08:19
  • @PLB, I thought the reasons for that are: (1) .find() must be true so .group() can be accessed; and (2) this leaves room for future implementation of this for multiple matches. – bruno.braga Feb 17 '13 at 11:13
  • @DanielHilgarth: Should I move the "solution" section to a self-answered format? – bruno.braga Feb 17 '13 at 11:14
  • @SunilKumarSahoo: this is weird, specially because it was also a reported bug in Android (as the link I placed in the question). Can you make sure it is compiled under with AndroidManifest as , and with the emulator 2.1? (I got the feeling that using an extended SDK (i.e., the additional Android.JAR file for higher version support) might put in the fixes for this even though you are in 2.1) – bruno.braga Feb 17 '13 at 11:17
  • @bruno.braga: Yes, please. Change your question to something like "Why does the following not produce the expected result in Android 2.1? [Regex], [Expected result] [actual result]" and answer it with "That's a know bug [link]. You have the following options: [a], [b], [c]". Like that, it's in a true Q&A format. – Daniel Hilgarth Feb 17 '13 at 13:44
  • @bruno.braga `if (m.find()) sb.append(m.group());` would be better, IMO. ;) – Leri Feb 18 '13 at 13:37
  • @DanielHilgarth: updated the thread in a question format. Hope it is fine now. thanks! – bruno.braga Feb 18 '13 at 14:54
  • @bruno.braga: Perfect, thanks! +1 for question and answer. – Daniel Hilgarth Feb 18 '13 at 14:55

1 Answers1

2

There is a bug in Android's regular expression, specifically for negative lookahead patterns.

Official ticket was created and fixed in Android 2.2 (Froyo): http://code.google.com/p/android/issues/detail?id=17159

The solution:

(a) Do not use Android 2.1 if you need this; or

(b) Rebuild your regex without negative pattern (might get dirtier, but should work)

bruno.braga
  • 1,001
  • 12
  • 21
  • A side note, for future reference: the m.matches() was required to be called, but it does not properly on Android 4+... just remove this, and it will work just fine. – bruno.braga Mar 18 '13 at 01:58