I am trying to use replace function to replace "('", "'" and "')" from the below string -
String foo = "('UK', 'IT', 'DE')";
I am trying to use the below code in order to do this operation -
(foo.contains("('")?foo.replaceAll("('", ""):foo.replace("'",""))?foo.replaceAll("')",""):foo
but its failing as -
java.util.regex.PatternSyntaxException: Unclosed group near index 2
Am I missing anything here?
replaceAll takes a regular expression as its search pattern. Since ( is a special character in regular expressions, it need to be escaped: '\\('. Furthermore, there’s no need for the contains test:
final String bar = foo.replaceAll("\\('", "") …
Lastly, you can combine all your replacements into one regular expression:
final String bar = foo.replaceAll("\\(?'([^']*)'\\)?", "$1");
// Output: UK, IT, DE
This will replace each occurrence of a single-quoted part inside your string with its content without the quotes, and it will allow (and discard) surrounding opening and closing parentheses.
foo.replaceAll("[(')]", "") will make the work )
As other answer(s) and the error message point out, replaceAll() deals with regular expressions, where the opening parenthesis ( has special meaning. Some characters have special meaning even in the replacement argument for the same reason.
If you want to be absolutely sure that your strings are going to behave as strings, there are two built-in "quote" methods (both are static) for "neutralizing" patterns:
Pattern.quote() for wrapping the replacee pattern
Matcher.quoteReplacement() for wrapping the replacement
Example code attempting to replaceAll() two ( to $ symbols:
System.out.println("Naive:");
try {
System.out.println("(("
.replaceAll("(", "$"));
} catch (Exception ex) {
System.out.println(ex);
}
System.out.println("\nPattern.quote:");
try {
System.out.println("q: "+Pattern.quote("("));
System.out.println("(("
.replaceAll(Pattern.quote("("), "$"));
} catch (Exception ex) {
System.out.println(ex);
}
System.out.println("\nPattern.quote+Matcher.quoteReplacement:");
try {
System.out.println("q: "+Pattern.quote("("));
System.out.println("qR: "+Matcher.quoteReplacement("$"));
System.out.println("(("
.replaceAll(Pattern.quote("("), Matcher.quoteReplacement("$")));
} catch (Exception ex) {
System.out.println(ex);
}
Output:
Naive:
java.util.regex.PatternSyntaxException: Unclosed group near index 1
(
Pattern.quote:
q: \Q(\E
java.lang.IllegalArgumentException: Illegal group reference: group index is missing
Pattern.quote+Matcher.quoteReplacement:
q: \Q(\E
qR: \$
$$
Of course by the time one knows about these methods, they have long got accustomed to escape the special characters manually.
Related
This question already has answers here:
Why does replaceAll fail with "illegal group reference"?
(8 answers)
Closed 4 years ago.
I've been trying to create a regex that matches the following pattern:
÷x%
here is my code:
String string = "÷x%2%x#3$$#";
String myregex = "all the things I've tried";
string = string.replaceAll(myregex,"÷1x#1$%");
I've tried the following regexes: (÷x%) , [÷][x][%] , [÷]{1}[x]{1}[%]{1}
I am using NetBeans IDE and it gives me an
Illegal group reference
However, when I change the value of string to something else, a word for example.
NetBeans does not give me an exception.
any thoughts, thanks
To replace all occurrences of a sub-string you don't need a pattern. You can use String.replace():
String input = "÷x%abc÷x%def÷x%";
String output = input.replace("÷x%", "÷1x#1$%");
System.out.println(output); // ÷1x#1$%abc÷1x#1$%def÷1x#1$%
As per method javadoc:
Replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence.
As per the comments in the question, I am hoping that this will shed some light on how the replaceAll works.
As per the JavaDoc, the replaceAll takes in a regular expression as first argument. In your case, the regular expression appears to be sound, so there is no issue there.
The second argument that the replaceAll accepts, is the string that will be used to replace whatever the regular expression matches.
In some cases, you will need to replace the same pattern with the same (hard coded, if you will) string:
String myString = "123abc1344";
myString = myString.replaceAll("\\d+", "number");
myString = myString.replaceAll("\\w+", "word");
System.out.println(myString); //Would yield something of the sort: numberwordnumber
BUT, there are situations were you want use chunks of what you are replacing in the replacement string itself. This is where the $ comes in:
String myString = "Age:9;Gender:Male";
Let us say that you want to change the format of the string to the following: "I am a {Gender} and I am {Age} years of age.".
In this case, your replacement string needs to extract information from the string to be replaced and inject it in the replacement itself. You do this by using the following:
String myString = "Age:9;Gender:Male";
myString = myString.replaceAll("Age:(\\d+);Gender:(\\w+)", "I am a $2 and I am $1 years of age.";
The above should yield the string that you are after. Notice that I am using $1 and $2 to access regular expression groups. In regular expression language, the 0th group is whatever it is matched by the entire regular expression. Any other round parenthesis denotes another regular expression group which you can access through the $ keyword.
This is why it needs to be escaped.
In the Java Regex you have to escape the $ sign.
If you write $% you would refer to the group % which is not existant.
You can try:
try {
String string = "÷x%2%x#3$$#";
String myregex = "÷x%";
String replace = "÷1x#1\\$%";
String resultString = string.replaceAll(myregex, replace);
} catch (PatternSyntaxException ex) {
// Syntax error in the regular expression
} catch (IllegalArgumentException ex) {
// Syntax error in the replacement text (unescaped $ signs?)
} catch (IndexOutOfBoundsException ex) {
// Non-existent backreference used the replacement text
}
I have this regular expression string:
^[a-zA-Z0-9\t\s\n\r!$()*,-./:;=?#`][{}_~|]+$
This RE should return true for the following:
!$()*,-./:;=?#`][{}_~|
I'm using RE of Apache and get false when running match function.
I think my regular expression is missing something, maybe handling with special characters.
The question is, what is wrong with my expression? here is my RE matching function:
public static String runRegularExpression(String string, String regularExpression, int parenthesis)
{
String result = null;
try
{
RE reCmd = new RE(regularExpression);
if (reCmd.match(string))
{
result = reCmd.getParen(parenthesis);
}
}
catch (Exception re)
{
}
return result;
}
You regex must not have unescaped hyphen in the middle of character class.
If you already have \s then there is no need to match \n and \t since \s matches all white-spaces that includes space, tab and newlines.
[a-zA-Z0-9_] can be shortened to \w
Backslashes need to be double escaped.
Try this regex:
^[\\w\\s\\r!$()*,./:;=?#`{}\\[\\]~|-]+$
A function receives something like this with special sign (,>_$' and Java replaceAll throwns error.
SAMPLE INPUT
I got an error if input something like this:
[ FAILED ] appendtext variable has with System.lineSeparator():
$model_fsdfdsfdsfdsfdsfds->load('fsdfdsfdsfdsfdsfds','dsfsdfsd');
$model_fsdfdsfdsfdsfdsfds->fsdfdsfdsfdsfdsfds->index();
No error if input as:
[ OKAY ] appendtext variable have simple input with System.lineSeparator():
mysomethingmodel
blabla
EXPLANATIONS
appendtext goes into String with other combinations:
String allappend = "Something simple var" + System.lineSeparator() + "\t{" + System.lineSeparator() + appendtext;
Okay. Than it goes into replaceAll with regex and thrown an error:
str_list = rs.replaceAll(regex_newlinebracket, allappend);
regex_newlinebracket is something regex from another function:
public String RegexPatternsFunction(String types, String function_name)
{
// get a rid of special sign
String function_name_quoted = Pattern.quote(function_name);
switch (types) {
case "newlinebracket":
return function_name_quoted + "(\\s|\\t|\\n)+[{]";
}
return null;
}
ERRORS
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Illegal group reference
at java.util.regex.Matcher.appendReplacement(Matcher.java:808)
at java.util.regex.Matcher.replaceAll(Matcher.java:906)
at java.lang.String.replaceAll(String.java:2162)
or exactly insider appendReplacement function from Matcher.java:
// The first number is always a group
refNum = (int)nextChar - '0';
if ((refNum < 0)||(refNum > 9))
throw new IllegalArgumentException(
"Illegal group reference");
cursor++;
PROBLEM
Using special characters as for the
$model_fsdfdsfdsfdsfdsfds->load('fsdfdsfdsfdsfdsfds','dsfsdfsd');
$model_fsdfdsfdsfdsfdsfds->fsdfdsfdsfdsfdsfds->index();
throwns an error in combination of replaceAll as Regex pattern.
A PROJECT WORKS IF NO SPECIAL SIGN.
I'm using Pattern.quote to escaping special characters in other words it will not works if come input like () and replaceAll using regex.
In C++ Qt, it's works well, in Java not.
Solutions?
It's fine (and necessary) that you use Pattern.quote. But what's causing the actual problem is the replacement string, since it contains $ (which is the relevant referencing-character in replacement strings). Luckily, Java provides you with another quoting function just to make replacement strings safe: Matcher.quoteReplacement()
So just try
allappend = Matcher.quoteReplacement(allappend);
str_list = rs.replaceAll(regex_newlinebracket, allappend);
I have the following string:
String s = "http://www.[VP_ANY].com:8080/servlet/[VP_ALL]";
I need to check if this string has the words [VP_ANY] o [VP_ALL]. I tried something like this (and many combinations), but it doesn't work:
Pattern.compile("\b(\\\\[VP_ANY\\\\]|\\\\[VP_ALL\\\\])\b").matcher(s).matches()
What am I doing wrong?
I tried the following:
s = "www.[VP_ANY].com:8080/servlet/[VP_ALL]";
System.out.println(Pattern.compile("\[VP_ANY\]").matcher(s).matches());
System.out.println(s.replaceAll("\[VP_ANY\]", "A"));
The first 'System.out' returns false, and the second one returns the replacement correctly.
I'm escaping the "[" and "]" characters with 2 backslashes, but when I save the post just one is showed. But I'm using 2 ...
Pattern.compile("\b(\\\\[VP_ANY\\\\]|\\\\[VP_ALL\\\\])\b").matcher(s).matches()
String s = "http://www.[VP_ANY].com:8080/servlet/[VP_ALL]";
^^ ^^ ^^ ^
NoWB NoWB NoWB WB
Your regex will not work because there is no word boundaray between . and [, between ] and . and between / and [
Additionally I think you are wrong with the escaping, your word boundaries would need a backslash more and the others two less.
So, since the word boundaries are not working, you should be fine with
Pattern.compile("\\[VP_(?:ANY|ALL)\\])")
Try this one
try {
boolean foundMatch = subjectString.matches("(?i)\\bVP_(?:ANY|ALL)\\b");
} catch (PatternSyntaxException ex) {
// Syntax error in the regular expression
}
or this
try {
boolean foundMatch = subjectString.matches("(?i)\\[VP_(?:ANY|ALL)\\]");
} catch (PatternSyntaxException ex) {
// Syntax error in the regular expression
}
Try This
\[VP_ANY\]|\[VP_ALL\]
My go at Java
try {
boolean foundMatch = "www.[VP_ANY].com:8080/servlet/[VP_ALL]".matches("\\[VP_ANY\\]|\\[VP_ALL\\]");
} catch (PatternSyntaxException ex) {
// Syntax error in the regular expression
}
"http://www.[VP_ANY].com:8080/servlet/[VP_ALL]".replaceAll ("http://www.(\\[VP_ANY\\]).com:8080/servlet/(\\[VP_ALL\\])", "$1:$2")
res117: java.lang.String = [VP_ANY]:[VP_ALL]
If you're looking for a literal [, you have to mask it - else it will mean a group like [A-Z].
Now if you read the regex from a file or a JTextField at runtime, that's all. But if you write it to your source code, the compiler will see the \ and treat it as a general masking, which might be needed to mask quotes like in
char apo = '\'';
String quote = "He said: \"Whut?\"";
So you have to mask it again, because only "\\" means "\".
So, for development, to not get too much confused, it is a fine idea to have a simple GUI-App with 2 or 3 textfields for testing regexps. If you succeed, you only have to add another level of masking, but to develop them, you can keep this second level away.
Divide et impera, like the ancient roman programmers told us.
I have a string and when I try to run the replaceAll method, I am getting this strange error:
String str = "something { } , op";
str = str.replaceAll("o", "\n"); // it works fine
str = str.replaceAll("{", "\n"); // does not work
and i get a strange error:
Exception in thread "main" java.util.regex.PatternSyntaxException:
Illegal repetition {
How can I replace the occurrences of "{" ?
A { is a regex meta-character used for range repetitions as {min,max}. To match a literal { you need to escape it by preceding it with a \\:
str = str.replaceAll("\\{", "\n"); // does work
If you really intend to replace single characters and not regexes (which is what you seem to want to do here), you should use .replace(), not .replaceAll(). In spite of its name, .replace() will replace ALL occurrences, not just the first one.
And in case you wonder, String implements CharSequence, so .replace("{", "\n") will work.
Escape it:
str = str.replaceAll("\\{", "\n");
This is needed since the first argument to replaceAll() is a regular expression, and { has a special meaning in Java regular expressions (it's a repetition operator, hence the error message).