【问题标题】:Replace multiple capture groups using regexp with java使用 regexp 用 java 替换多个捕获组
【发布时间】:2015-02-09 12:11:26
【问题描述】:

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

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,%,# 等,并且只有与每种类型的开头和结尾匹配的单词才会被删除这些字符,并且嵌入在单词中的相同字符保留在原处。

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

我可以提供一个模式,例如\\b8([^\\s]*)8\\b|\\b9([^\\s]*)9\\b .. 等等,它将匹配所有类型的匹配对 *8,9,..),但是我如何指定一个“变量”替换组 -

例如如果匹配是 9...9,则替换应该是 $2。

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

或者有完全不同的方法来解决这个问题?

谢谢。

【问题讨论】:

    标签: java regex


    【解决方案1】:

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

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

    或

    (?<!\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
    

    说明:

    • (?&lt;!\\S) Negative lookbehind,断言匹配不会以非空格字符开头。
    • (\\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

    【讨论】:

    • 谢谢。正如您和其他人所建议的那样,使用反向引用和捕获组到 2 似乎已经成功了。我正在使用以下 (?
    • @ssen 你明白了。更精简了(?&lt;!\S)([89&amp;#%])(\S+)\1(?=\s|$)regex101.com/r/qB0jV1/19
    【解决方案2】:
    (?<![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])
    

    如果您有很多分隔符,请使用它。

    【讨论】:

      猜你喜欢
      • 2017-10-13
      • 1970-01-01
      • 2021-12-01
      • 1970-01-01
      • 2021-11-12
      • 1970-01-01
      • 1970-01-01
      • 2012-01-16
      • 1970-01-01
      相关资源
      最近更新 更多