Как 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: изменил пример регулярного выражения, чтобы показать, что не весь шаблон сгруппирован.
Ответы
Ответ 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: Недопустимая ссылка группы"