Очистка ввода перед использованием appendReplacement с сопоставлением с образцом - PullRequest
0 голосов
/ 04 марта 2020

У меня проблема с методом appendReplacement. Я обрабатываю много источников, и бывает, что некоторые из них содержат именованную группу (например, ${name}).

Пример кода:

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

public class HelloWorld{

     private static final Pattern SOURCE_BLOCK_PATTERN = Pattern.compile("<source>.*?</source>");

     public static void main(String []args){
        String inputText = "<p>something</p> <source> <p> @${xx} </p> </source> <p>something</p>";

        Matcher matcher = SOURCE_BLOCK_PATTERN.matcher(inputText);
        StringBuffer buffStr = new StringBuffer();

        while (matcher.find()) {
            String group = matcher.group();
            group = group.replaceAll("<[/]?p>", "");
            matcher.appendReplacement(buffStr, group);
        }
        matcher.appendTail(buffStr);
        String outputText = buffStr.toString();

     }
}

И результат:

Exception in thread "main" java.lang.IllegalArgumentException: No group with name {xx}
    at java.util.regex.Matcher.appendReplacement(Matcher.java:849)
    at HelloWorld.main(HelloWorld.java:17)

Как мне выполнить такую ​​замену, чтобы не было ошибок?

1 Ответ

0 голосов
/ 04 марта 2020

Как уже упоминалось здесь

Знак доллара ($) может быть включен в качестве литерала в строку замены, если ему предшествует обратная косая черта sh (\ $) .

Итак, изменив вызов метода на:

matcher.appendReplacement(buffStr, group.replace("$","\\$"));

Я получил ожидаемый результат, ничего не нарушая.

...