是否可以对非捕获组进行反向引用?

时间:2012-11-04 01:26:13

标签: java regex backreference

我正在尝试创建一个与replaceAll()一起使用的正则表达式/替换对,它将捕获目标字符串之前和之后的字符。

这是我的版本,适用于简单的情况:

String adjacent = "fooaXbcXdbar".replaceAll(".*?(.)X(.).*?(?=(.X)|$)", "$1$2");

根据需要生成"abcd"(最后的结果是消耗到字符串的结尾,使得对replaceAll()的单个调用工作。)

然而,当目标之后的角色也是目标之前的角色时,我似乎无法解决一个边缘情况:

String adjacent = "fooaXbXdbar".replaceAll(".*?(.)X(.).*?(?=(.X)|$)", "$1$2");

生成"ab",但我希望"abbd"。正则表达式消耗了匹配的前导部分,使得以下输入不匹配。

我试过环顾四周,但似乎无法让它发挥作用。


注意:我对涉及循环或代码等的解决方案不感兴趣。只是寻找适用于所提到的边缘情况的正则表达式和替换字符串。

1 个答案:

答案 0 :(得分:2)

这个怎么样:

String adjacent =
    "fooaXbXdbar".replaceAll(".*?(.)X(?:(?=(.)X)|(.).*?(?=.X|$))", "$1$2$3");

它的作用是,在X之后,它首先检查它是否紧跟.X,在这种情况下,它会将.捕获为$2并且认为比赛完成;如果它发现后面紧跟.X,它继续使用您已经使用的相同逻辑,将后续字符捕获为$3

(注意:我已经用你的两个例子对它进行了测试,但显然它可能会遗漏你需要支持的其他情况。我建议你自己测试一下。)