循环浏览正则表达式匹配项并替换当前匹配项 - java

考虑以下字符串:

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

假设您需要将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.");
}

这样的输出将是:

他在薄皮上点了一个凤尾鱼薄饼。不幸的是,这不是他想要的。此外,带有蘑菇,意大利辣香肠和凤尾鱼的比萨饼比带有薄壳的凤尾鱼比萨要好得多。

发生了什么:

第一个匹配项pizza with anchovies与最后一个匹配项相同。因此,使用String.replace会使第一个和最后一个匹配更改为pizza with anchovies on a thin crust。由于我们正在循环浏览所有匹配项,因此最后一个匹配项仍将发生,并且replace函数也将替换第一个匹配项(因为第一个匹配项和最后一个匹配项相同)。因此,我们得到了双重on a thin crust

问:

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

参考方案

使用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.

见Java demo

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

Java Regex:将整个单词与单词边界匹配 - java

我正在尝试使用Java检查字符串是否整体上包含一个单词。以下是一些示例:Text : "A quick brown fox" Words: "qui" - false "quick" - true "quick brown" - true "ox" - fal…

java split regex-字符的任意组合 - java

我正在使用3个字符分割字符串:空格,破折号和逗号我想要的是能够使用这3个字符的任意组合进行拆分,例如:-,(破折号后跟逗号)或,--(逗号后加2破折号)或- , -(破折号,逗号间隔破折号)等 String address = "Sector -18B, Dwarka"; String[] addressParts = address.s…

Java RegEx中的单词边界\ b - java

我在使用\b作为Java Regex中的单词定界符时遇到困难。对于text = "/* sql statement */ INSERT INTO someTable"; Pattern.compile("(?i)\binsert\b");找不到匹配项Pattern insPtrn = Pattern.compile(&…

Java:线程池如何将线程映射到可运行对象 - java

试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…