Как добавить замену на группу Matcher вместо всего шаблона? - PullRequest
24 голосов
/ 15 октября 2010

Я использую 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));
}

Нечто подобное, когда оно заменяет только определенную группу, а не весь Образец.

РЕДАКТИРОВАТЬ: изменил пример регулярного выражения, чтобы показать, что не все шаблоны сгруппированы.

Ответы [ 2 ]

32 голосов
/ 24 марта 2011

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

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

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

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

17 голосов
/ 15 октября 2010

Допустим, что весь ваш шаблон соответствует "(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 остаются нетронутыми,фактически заменяется только инфикс.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...