简体   繁体   中英

Java String ReplaceAll and ReplaceFirst Fails at $ Symbol at Replacement Text

I wrote this code:

public static void main(String args[]) throws Exception {
    String template = "The user has spent amount in a day";
    String pattern = "amount";
    String output = template.replaceAll(pattern, "$ 100");
    System.out.println(output);
}

This is what happens when I run it:

Exception in thread "main" java.lang.IllegalArgumentException: Illegal group reference
        at java.util.regex.Matcher.appendReplacement(Matcher.java:713)
        at java.util.regex.Matcher.replaceAll(Matcher.java:813)
        at java.lang.String.replaceAll(String.java:2190)
        at demo.BugDemo.main(BugDemo.java:16)
Java Result: 1

I'm reading data from a file. Should I escape all $ symbols in the file data, or is this an unnecessary process? Is there any other class or library to handle this situation?

What is the problem with having a special symbol in the replacement text (not in the regex)?

Notes:

  • I don't want to check every character to escape. That's why I am asking this question.

  • I'm using Java 6.

String.replaceAll takes a regular expression matching pattern as its first parameter, and a regular expression replacement pattern as its second parameter - and $ has a specific meaning in regular expressions (in both matching patterns and replacement patterns, although in different senses).

Just use String.replace instead, and I suspect all your problems will go away. You should only use replaceAll when you genuinely want to match/replace via a regular expression - which I don't think you do in this case.

EDIT: As to your question:

What is the problem with having a special symbol in the replacement text (not in the regex)?

Again, the documentation for replaceAll makes this clear:

Note that backslashes (\\) and dollar signs ($) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string; see Matcher.replaceAll . Use Matcher.quoteReplacement(java.lang.String) to suppress the special meaning of these characters, if desired.

So if you want to treat the matching pattern as a regular expression, but not the replacement, then use Matcher.quoteReplacement .

In a replacement string, $ is a special character: it is used to grab matched groups from the pattern you are replacing. You can read more about it here .

To fix this, you can quote the replacement string to remove all special meaning from $ characters:

import java.util.regex.Matcher;
// ...
String output = template.replaceAll(pattern, Matcher.quoteReplacement("$ 100"));

Try this one

 String template = "The user has spent amount in a day";
 String pattern = "amount";
 String output = template.replaceAll(pattern, "\\$ 100");
 System.out.println(output);

Special character $ can be handled is simple way. Check below example

public static void main(String args[]){
        String test ="Other company in $ city ";
        String test2 ="This is test company ";
        try{
            test2= test2.replaceFirst(java.util.regex.Pattern.quote("test"),  Matcher.quoteReplacement(test));
            System.out.println(test2);
            test2= test2.replaceAll(java.util.regex.Pattern.quote("test"),  Matcher.quoteReplacement(test));
            System.out.println(test2);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

Output:

This is Other company in $ city  company 
This is Other company in $ city  company 

$ is used a symbol to specify the replacement group. You need to escape it:

String output = template.replaceAll(pattern, "\\$ 100");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM