The java.util.regex.PatternSyntaxException: Dangling meta character near index 0 example shows the reasons for this exception. It also shows how to fix it using various solutions.
What is java.util.regex.PatternSyntaxException: Dangling meta character near index 0 and what causes it?
As the exception message suggests, if we try to match a meta-characters in a literal way in a regex pattern without escaping it, Java throws this exception. What is a meta-character? Well, in a regular expression, certain characters have a special meaning, for example, “+” (plus sign) matches the previous pattern one or more times. We have to escape these characters before we can match these in a literal way.
Here are some of the reasons for this exception to occur and their fixes.
Reason 1: Trying to split a string using one of the meta-characters
You are trying to split a string using the Java String split method using one of the regular expression meta-characters.
Consider below given example where we are trying to split the string content using the “+” sign.
1 2 3 4 5 6 |
String str = "One+Two+Three"; String[] parts = str.split("+"); for(String part : parts) { System.out.println(part); } |
Output
1 2 3 4 5 6 7 8 9 10 11 |
Exception in thread "main" java.util.regex.PatternSyntaxException: Dangling meta character '+' near index 0 + ^ at java.util.regex.Pattern.error(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.lang.String.split(Unknown Source) at java.lang.String.split(Unknown Source) |
Solution:
Since the split
method accepts a regex pattern, we need to escape the meta-characters using “\\” before matching them literally. These characters include “+”, “*”, “^”, “|”, and others.
1 2 3 4 5 6 |
String str = "One+Two+Three"; String[] parts = str.split("\\+"); for(String part : parts) { System.out.println(part); } |
Output
1 2 3 |
One Two Three |
Reason 2: Trying to replace substring having a meta-character using the replaceAll method
Just like the split
method, the Java String replaceAll method also accepts the regex pattern. Trying to match specific meta-character in a literal way without escaping it causes the same exception as given below.
1 2 |
String str = "Resolution is: 1080 * 1920"; System.out.println(str.replaceAll("*", "x")); |
Output
1 2 3 4 5 6 7 8 9 10 |
Exception in thread "main" java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0 * ^ at java.util.regex.Pattern.error(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.lang.String.replaceAll(Unknown Source) |
Solution:
Escape all meta-characters using “\\” in the replaceAll
method as below.
1 2 |
String str = "Resolution is: 1080 * 1920"; System.out.println(str.replaceAll("\\*", "x")); |
Output
1 |
Resolution is: 1080 x 1920 |
Reason 3: Problem with the regular expression pattern
The regex pattern we have mentioned has a problem. Consider below given example where I am not trying to match any meta-character literally, but still, the code will throw the exception due to incorrect usage of the “*” meta-character.
1 2 3 4 5 6 |
Pattern pattern = Pattern.compile("*\\[a-z\\]"); Matcher matcher = pattern.matcher("[One],[Two],[Three]"); while(matcher.find()) { System.out.println("Matched \"" + matcher.group() + "\""); } |
Output
1 2 3 4 5 6 7 8 9 |
Exception in thread "main" java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0 *\[a-z\] ^ at java.util.regex.Pattern.error(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) |
Solution:
The solution is to fix the regular pattern. In the above example, the usage of the “*” is incorrect. The “*” matches the previous pattern zero or more times. Since the “*” is mentioned at the start of the pattern, there is no previous pattern or group to match zero or more times. Removing the * will fix the exception.
Important Note:
Not all unescaped meta-characters cause this exception. But when the intention is to match them literally, unescaped meta-characters will not produce the desired result. See the below example where we want to split the string by pipe (“|”), but the code does not produce the desired result.
1 2 3 4 5 6 |
String str = "One|Two|Three"; String[] parts = str.split("|"); for(String part : parts) { System.out.println(part); } |
Output
1 2 3 4 5 6 7 8 9 10 11 12 13 |
O n e | T w o | T h r e e |
Well, that was not the desired output. The reason is, the pipe character is a meta-character in regex and we tried to match it literally without escaping it.
If you want to get the complete list of the java regex meta-characters, please visit Java Regular Expression Tutorial with Examples.
Please let me know your views in the comments section below.