Заменить каждое второе вхождение строки c помощью регулярного выражения RegEx на Java

Строка "Object-oriented programming is a programming language model organized around objects rather than "actions" and data rather than logic. Object-oriented programming blabla. Object-oriented programming bla."

Должна быть преобразована в "Object-oriented programming is a programming language model organized around objects rather than "actions" and data rather than logic. OOP blabla. Object-oriented programming bla."

Не смог понять, как добавить индекс чётных matcher для замены каждого второго совпадения.

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

public class ReplaceStringDemo {
    public static void main(String[] args) {
        String text = ("Object-oriented programming is a programming language model "
                + "organized around objects rather than \"actions\" and data rather than logic. "
                + "Object-oriented programming blabla. Object-oriented programming bla.");
        Pattern pattern = Pattern.compile("object-oriented programming", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(text);
        
        while (matcher.find()) {
            int start = matcher.start();
            int end = matcher.end();
            System.out.println("Найдено совпадение " + text.substring(start,end)
                                + " с " + start + " по " + (end-1) + " позицию");   
        }
            System.out.println(matcher.replaceFirst("OOP"));
    }
}

Ответы (1 шт):

Автор решения: Nowhere Man

Для этого нужно использовать сответствующее регулярное выражение, в самом простом случае:

public static String replaceEachOther(String str, String word, String replacement) {
    return str.replaceAll("(" + word +".*?)" + word, "$1" + replacement);
}

Также может понадобиться экранировать искомое словосочетание, преобразовав его в литерал при помощи метода Pattern::quote, или же добавив пару \Q / \E. Дополнительно могут потребоваться флаги:

  • ?s - DOTALL - игнорировать переносы строк
  • ?i - CASE_INSENSITIVE - игнорировать регистр (только для английского алфавита)
  • ?u - UNICODE_CASE - игнорировать регистр для Unicode символов (например, кириллицы)
public static String replaceEachOther(String str, String word, String replacement) {
    word = "\\Q" + word + "\\E"; // Pattern.quote(word)
    return str.replaceAll("(?siu)(" + word +".*?)" + word, "$1" + replacement);
}

Тест:

String str = "aaa bbb ccc ddd aaa. aa bbb aaa. aaa ddd fgg. aaa faaab saa";

System.out.println(replaceEachOther(str, "aaa", "[A*A]"));

str = "Объедко-ориентированное программирование раз, \nобъедко-ориентированное программирование, два! Объедко-ориентированное программирование - 3!";
System.out.println(replaceEachOther(str, "Объедко-ориентированное программирование", "ООП"));
aaa bbb ccc ddd [A*A]. aa bbb aaa. [A*A] ddd fgg. aaa f[A*A]b saa
Объедко-ориентированное программирование раз, 
ООП, два! Объедко-ориентированное программирование - 3!
→ Ссылка