Подтвердить что ты не робот

Как appendReplacement в группе Matcher вместо всего шаблона?

Я использую while(matcher.find()) для прокрутки всех совпадений шаблона. Для каждого экземпляра или соответствия этого шаблона, который он находит, я хочу заменить matcher.group(3) на некоторый новый текст. Этот текст будет отличаться для каждого из них, поэтому я использую matcher.appendReplacement() для восстановления исходной строки с новыми изменениями по мере ее прохождения. Однако appendReplacement() заменяет весь шаблон вместо группы.

Как я могу это сделать, но только изменить третью группу соответствия, а не весь шаблон?

Вот пример кода:

Pattern pattern = Pattern.compile("THE (REGEX) (EXPRESSION) (WITH MULTIPLE) GROUPS");
Matcher matcher = pattern.matcher("THE TEXT TO SEARCH AND MODIFY");
StringBuffer buffer = new StringBuffer();

while(matcher.find()){
   matcher.appendReplacement(buffer, processTheGroup(matcher.group(3));
}

но я хотел бы сделать что-то вроде этого (очевидно, это не работает).

...
while(matcher.find()){
   matcher.group(3).appendReplacement(buffer, processTheGroup(matcher.group(3));
}

Что-то вроде этого, где он заменяет только определенную группу, а не весь шаблон.

EDIT: изменил пример регулярного выражения, чтобы показать, что не весь шаблон сгруппирован.

4b9b3361

Ответ 1

Скажем, весь ваш шаблон соответствует "(prefix)(infix)(suffix)", захватив 3 части в группы 1, 2 и 3 соответственно. Теперь предположим, что вы хотите заменить только группу 2 (инфикс), оставив префикс и суффикс неповрежденными так, как они были.

Затем вы добавляете то, что group(1) соответствует (неизмененному), новая замена для group(2) и что group(3) соответствует (неизмененному), что-то вроде этого:

matcher.appendReplacement(
    buffer,
    matcher.group(1) + processTheGroup(matcher.group(2)) + matcher.group(3)
);

Это все равно будет соответствовать и заменять весь шаблон, но поскольку группы 1 и 3 остаются нетронутыми, эффективно заменяется только инфикс.

Вы должны иметь возможность адаптировать один и тот же базовый метод для вашего конкретного сценария.

Ответ 2

Я вижу, что у этого уже есть принятый ответ, но он не совсем корректен. Правильный ответ выглядит примерно так:

.appendReplacement("$1" + process(m.group(2)) + "$3");

Это также иллюстрирует, что "$" является специальным символом в .appendReplacement. Поэтому вы должны позаботиться о своей функции "process()", чтобы заменить все "$" на "\ $". Matcher.quoteReplacement(replacementString) сделает это за вас (спасибо @Med)

Предыдущий принятый ответ не удастся, если в группах 1 или 3 содержится "$" . Вы получите "java.lang.IllegalArgumentException: Недопустимая ссылка группы"