gsgx
gsgx

Reputation: 12249

PatternSyntaxException: Illegal Repetition when using regex in Java

I don't know much regex, but I need to match a simple pattern. The following should return true,

Pattern.matches("{\"user_id\" : [0-9]*}", inputLine)

when inputLine is

{"user_id" : 34}

However, I'm getting this exception:

java.util.regex.PatternSyntaxException: Illegal repetition
{"user_id" : 24}
    at java.util.regex.Pattern.error(Unknown Source)
    at java.util.regex.Pattern.closure(Unknown Source)
    at java.util.regex.Pattern.sequence(Unknown Source)
    at java.util.regex.Pattern.expr(Unknown Source)
    at java.util.regex.Pattern.compile(Unknown Source)
    at java.util.regex.Pattern.<init>(Unknown Source)
    at java.util.regex.Pattern.compile(Unknown Source)
    at java.util.regex.Pattern.matches(Unknown Source)
    at org.whispercomm.manes.server.http.IntegrationTest.createUser(IntegrationTest.java:173)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

What am I doing wrong?

Upvotes: 132

Views: 130879

Answers (3)

Jorge Tovar
Jorge Tovar

Reputation: 1869

@IntelliJ IDE for example detects the inconsistency. Depending on the input, What you could do is to escape the characters or handle the problem using the data provided by the exception.

enter image description here

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public class StackOverflow {
    private static String REGEX = "{\"user_id\" : [0-9]*}";

    public static void main(String[] args) {
        try {
            Pattern pattern = Pattern.compile(REGEX);

            // get a matcher object
            String input = "Hello stackoverflow";
            Matcher matcher = pattern.matcher(input);
            input = matcher.replaceAll("something");
        } catch (PatternSyntaxException e){
            System.out.println("PatternSyntaxException: ");
            System.out.println("Description: "+ e.getDescription());
            System.out.println("Index: "+ e.getIndex());
            System.out.println("Message: "+ e.getMessage());
            System.out.println("Pattern: "+ e.getPattern());
        }
    }
}

Output

PatternSyntaxException: 
Description: Illegal repetition
Index: 1
Message: Illegal repetition near index 1
{"user_id" : [0-9]*}
 ^
Pattern: {"user_id" : [0-9]*}

Possible solution


catch... ex
    StringBuilder sb = new StringBuilder(text);
    sb.insert(ex.getIndex() + 1, "\\");
    matcher.replaceAll(sb.toString())

Upvotes: 0

fge
fge

Reputation: 121720

The { and } are special in Java's regex dialect (and most other dialects for that matter): they are the opening and closing tokens for the repetition quantifier {n,m} where n and m are integers. Hence the error message: "Illegal repetition".

You should escape them: "\\{\"user_id\" : [0-9]*\\}".

And since you seem to be trying to parse JSON, I suggest you have a look at Jackson.

Upvotes: 233

Jirka Kopřiva
Jirka Kopřiva

Reputation: 3089

There should be plus operator:

user_id : [0-9]+

Double apostrophes only when the string has to contain it.

When the string including curly brackets use:

\{user_id : [0-9]+\}

Upvotes: 7

Related Questions