java - 循环遍历 RegEx 匹配并替换当前匹配

标签 java regex

考虑以下字符串:

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.

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

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

(?i:pizza with [a-zA-Z,\s]*?anchovies)

这会捕获三个匹配项。然后,我继续使用以下代码将 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.");
}

这样的输出将是:

He ordered a pizza with anchovies on a thin crust on a thin crust. Unfortunately, it wasn't the thing he wanted. Besides, pizza with mushroom, pepperoni and anchovies is much better than the normal pizza with anchovies on a thin crust on a thin crust.

发生了什么:

第一场比赛 pizza with anchovies 与最后一场比赛相同。因此,使用 String.replace 会导致第一个和最后一个匹配项更改为 pizza with anchovies on a thin crust。因为,我们正在遍历所有匹配项,所以最后一个匹配项仍然会出现,替换函数也将替换第一个匹配项(因为第一个匹配项和最后一个匹配项是相同的)。因此,我们得到了双倍的薄壳

问:

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

最佳答案

通过使用 $0 对整个匹配项的反向引用,通过单个 replaceAll 完成此操作:

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.

参见 Java demo

这样一来,您将避免替换已经替换的文本,因为 replaceAll() 会处理满足您的正则表达式模式的所有、多个、非重叠的子字符串。

关于java - 循环遍历 RegEx 匹配并替换当前匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43536696/

相关文章:

java - 在 sling servlet 中调用除 doGet 或 doPost 之外的不同方法

java - 如何覆盖Accumulo中SortedKeyValueIterator接口(interface)的功能?

r - 提取某个子字符串(电子邮件地址)

regex - sparql regex 比较两个字符串变量(一个由另一个组成)

javascript - 使用 RegExp、String 或其他方法确定类中声明的属性的值类型

java - WSO2 API Manager安装无法运行Java

java - hibernate ,JDBC : Error calling Driver#connect

java - 如何使用反射获取匿名类字段

python - 在 Django 中使用 Python 正则表达式

r - 如何匹配不同的重复字符