1

I have something similar to the following code in my Android app,

val regex = Regex("\\$\\{}")

It works well for the unit tests in src/test, but it throws PatternSyntaxException for the unit tests in src/androidTest, and when I run the whole app, it has the same exception.

Here is the exception details

java.util.regex.PatternSyntaxException: Syntax error in regexp pattern near index 5
\$\{}
     ^
    at com.android.icu.util.regex.PatternNative.compileImpl(Native Method)
    at com.android.icu.util.regex.PatternNative.<init>(PatternNative.java:39)
    at com.android.icu.util.regex.PatternNative.create(PatternNative.java:35)
    at java.util.regex.Pattern.compile(Pattern.java:1426)
    at java.util.regex.Pattern.<init>(Pattern.java:1401)
    at java.util.regex.Pattern.compile(Pattern.java:959)
    at kotlin.text.Regex.<init>(Regex.kt:89)

I have to write this way to make it work in Android Environment.

val regex = Regex("\\$\\{\\}")

But android studio will complain about this enter image description here

Anyone knows why this happens?

1 Answer 1

3

You appear to have found a bug. { must be escaped; } is a weird beast: If you intend to match an actual }, you must ordinarily escape it, however, what happens if a regex contains a closing } that has no matching opener? The regex spec is not particularly clear about this; the obvious choices are to either fail, or, to treat it as a literal }. That last one is trying to assume that the programmer must be infinitely wise and incapable of error, and is therefore utterly stupid, and yet, android studio is forcing you into this stupity. There is one (bad) reason to work this way, which is that the modus operandi in regexes is 'hey if it makes no sense, assume the literal is intended', but this isn't universal (generally, ) must always be escaped, for example). It shows up in having a - within a [] block at an edge, then it is interpreted as a literal.

The 'fix' seems to me to be to accept the behaviour of androidTest because this is such a weird corner case, and 'throw an exception' is usually a better choice than 'make bizarre assumptions about what this garbage is supposed to mean'. They are 2 completely different regex engines, differences in unspecced corner cases are presumably inevitable, and a mindset of 'they must become exactly the same in all ways' is therefore unworkable.

TL;DR:

  • The right regex is to escape the }, always, even if you have an engine that doesn't need it.
  • Send a bug report to android studio/intellij that their warning is bad and needs to be removed. In fact, the opposite is more warranted, and state the case that e.g. the android internal engine demands the \\.
Sign up to request clarification or add additional context in comments.

Comments

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.