Java String ReplaceAll и ReplaceFirst сбой в $Symbol при тексте замены - программирование

Java String ReplaceAll и ReplaceFirst сбой в $Symbol при тексте замены

Я написал этот код:

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);
}

Это то, что происходит, когда я запускаю его:

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

Я читаю данные из файла. Должен ли я избегать всех $ символов в файлах данных или это ненужный процесс? Есть ли какой-либо другой класс или библиотека для обработки этой ситуации?

В чем проблема с наличием специального символа в заменяющем тексте (не в регулярном выражении)?

Примечания:

  • Я не хочу проверять каждого персонажа, чтобы убежать. Вот почему я задаю этот вопрос.

  • Я использую Java 6.

4b9b3361

Ответ 1

String.replaceAll использует шаблон, соответствующий регулярному выражению, в качестве его первого параметра, а шаблон замены регулярных выражений в качестве второго параметра - и $ имеет определенное значение в регулярных выражениях (как в совпадающих шаблонах, так и в шаблонах замещения, хотя в разных смыслах).

Просто используйте String.replace, и я подозреваю, что все ваши проблемы исчезнут. Вы должны использовать только replaceAll, когда вы действительно хотите сопоставить/заменить через регулярное выражение, которое я не думаю, что вы делаете в этом случае.

EDIT: Что касается вашего вопроса:

В чем проблема с наличием специального символа в заменяющем тексте (не в регулярном выражении)?

И снова документация для replaceAll делает это ясным:

Обратите внимание, что обратная косая черта (\) и знаки доллара ($) в заменяющей строке могут привести к тому, что результаты будут отличаться от того, будут ли они рассматриваться как буквальная строка замены; см. Matcher.replaceAll. Используйте Matcher.quoteReplacement(java.lang.String) для подавления специального значения этих символов, если это необходимо.

Итак, если вы хотите рассматривать шаблон соответствия как регулярное выражение, но не замену, используйте Matcher.quoteReplacement.

Ответ 2

В заменяющей строке $ является специальным символом: он используется для захвата сопоставленных групп из шаблона, который вы заменяете. Вы можете прочитать об этом здесь.

Чтобы исправить это, вы можете указать строку замены, чтобы удалить все специальные значения из $ символов:

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

Ответ 3

$ используется символ для указания группы замещения. Вам нужно избегать этого:

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

Ответ 4

Попробуйте этот

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

Ответ 5

Специальный символ $может обрабатываться простым способом. Пример ниже

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();
        }
    }

Вывод:

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