使用带有java的正则表达式替换多个捕获组

时间:2014-12-11 04:53:09

标签: java regex

我有这个要求 - 对于输入字符串,如下所示

8This8 is &reallly& a #test# of %repl%acing% %mul%tiple 9matched9 9pairs

我想剥离匹配的字边界(匹配对为8或&或%等)并将导致以下

This is really a test of repl%acing %mul%tiple matched 9pairs

用于这些对的字符列表可以改变,例如, 8,9,%,#etc,只有与每种类型匹配开头和结尾的单词将被删除这些字符,并在单词中保留相同的字符。

使用 Java 我可以将模式设为\\b8([^\\s]*)8\\b并替换为$ 1,以捕获并替换所有出现的8 ... 8,但我该如何为所有对的类型?

我可以提供\\b8([^\\s]*)8\\b|\\b9([^\\s]*)9\\b等等模式,以匹配所有类型的匹配对* 8,9,..),但如何指定'变量'替换组 - < / p>

e.g。如果比赛是9 ... 9,那么替补应该是2美元。

我当然可以通过其中的多个来运行它,每个都替换一个特定类型的对,但我想知道是否有更优雅的方式。

或者是否存在完全不同的方法来解决这个问题?

感谢。

2 个答案:

答案 0 :(得分:3)

您可以使用以下正则表达式,然后将匹配的字符替换为组索引2中的字符。

(?<!\S)(\S)(\S+)\1(?=\s|$)

OR

(?<!\S)(\S)(\S*)\1(?=\s|$)

Java正则表达式,

(?<!\\S)(\\S)(\\S+)\\1(?=\\s|$)

DEMO

String s1 = "8This8 is &reallly& a #test# of %repl%acing% %mul%tiple 9matched9 9pairs";
System.out.println(s1.replaceAll("(?<!\\S)(\\S)(\\S+)\\1(?=\\s|$)", "$2"));

输出:

This is reallly a test of repl%acing %mul%tiple matched 9pairs

<强>解释

  • (?<!\\S)负面反馈,断言匹配不会以非空格字符开头。
  • (\\S)捕获第一个非空格字符并将其存储到组索引1中。
  • (\\S+)捕获一个或多个非空格字符。
  • \\1指第一个捕获组内的角色。
  • (?=\\s|$)并且匹配必须后跟行锚的空格或末尾。
  • 这可确保字符串的第一个字符和最后一个字符必须相同。如果是这样,那么它将用组索引2中存在的字符替换整个匹配。

对于这种特定情况,您可以将上述正则表达式修改为

String s1 = "8This8 is &reallly& a #test# of %repl%acing% %mul%tiple 9matched9 9pairs";
System.out.println(s1.replaceAll("(?<!\\S)([89&#%])(\\S+)\\1(?=\\s|$)", "$2"));

DEMO

答案 1 :(得分:1)

(?<![a-zA-Z])[8&#%9](?=[a-zA-Z])([^\s]*?)(?<=[a-zA-Z])[8&#%9](?![a-zA-Z])

尝试使用$1\1替换。请参阅演示。

https://regex101.com/r/qB0jV1/15

(?<![a-zA-Z])[^a-zA-Z](?=[a-zA-Z])([^\s]*?)(?<=[a-zA-Z])[^a-zA-Z](?![a-zA-Z])

如果您有许多分隔符,请使用此选项。