循环通过RegEx匹配并替换当前匹配

Kaw*_*shi 6 java regex

请考虑以下字符串:

他点了凤尾鱼披萨.不幸的是,这不是他想要的.此外,配有蘑菇,意大利辣香肠和凤尾鱼的披萨比配凤尾鱼的普通披萨要好得多.

假设您需要更改pizza with (ingredients)pizza with (ingredients) on a thin crust.

为此,我设置了一个正则表达式:

(?i:pizza with [a-zA-Z,\s]*?anchovies)
Run Code Online (Sandbox Code Playgroud)

这抓住了三场比赛.然后,我继续on a thin crust使用以下代码添加到每个匹配:

Pattern p = Pattern.compile("(?i:pizza with [a-zA-Z,\s]*?anchovies)");
Matcher m = p.matcher(string);
while(m.find())
{
    string = string.replace(m.group(), m.group() + "on a thin crust.");
}
Run Code Online (Sandbox Code Playgroud)

然后输出将是:

他在薄薄的外皮上点了一块披着凤尾鱼的薄饼.不幸的是,这不是他想要的.此外,配有蘑菇,意大利辣香肠和凤尾鱼的比萨饼比普通的披萨要好得多,而薄皮上的薄皮上有凤尾鱼.

发生了什么:

第一场比赛pizza with anchovies与上一场比赛相同.因此,使用String.replace导致第一个和最后一个匹配变为pizza with anchovies on a thin crust.因为,我们循环遍历所有匹配,最后的匹配仍将发生,并且替换函数也将替换第一个匹配(因为第一个匹配和最后一个匹配是相同的).因此,我们得到了两倍on a thin crust.

问:

有没有办法在当前比赛中替换正则表达式匹配?

Wik*_*żew 6

与单一的做replaceAll$0反向引用整场比赛:

String s = "He ordered a pizza with anchovies. Unfortunately, it wasn't the thing he wanted. Besides, pizza with mushroom, pepperoni and anchovies is much better than the normal pizza with anchovies.";
s = s.replaceAll("(?i)pizza with [a-zA-Z,\\s]*?anchovies", "$0 on a thin crust");
System.out.println(s);
// => He ordered a pizza with anchovies on a thin crust. Unfortunately, it wasn't the thing 
//    he wanted. Besides, pizza with mushroom, pepperoni and anchovies on a thin crust is 
//    much better than the normal pizza with anchovies on a thin crust.
Run Code Online (Sandbox Code Playgroud)

请参阅Java演示

这样,您将避免替换已经替换的文本,因为replaceAll()处理满足您的正则表达式模式的子串的所有,多个,非重叠的出现.