我正在尝试创建一个正则表达式/替换对,与 replaceAll()
一起使用,它将捕获目标字符串之前和之后的字符。
这是我的版本,适用于简单的情况:
String adjacent = "fooaXbcXdbar".replaceAll(".*?(.)X(.).*?(?=(.X)|$)", "$1$2");
根据需要生成“abcd”
(最后的展望是消耗到字符串的末尾,从而使对replaceAll()
的单次调用起作用)。
但是,当目标后面的字符也是目标之前的字符时,我似乎无法解决一个边缘情况:
String adjacent = "fooaXbXdbar".replaceAll(".*?(.)X(.).*?(?=(.X)|$)", "$1$2");
产生“ab”
,但我想要“abbd”
。正则表达式消耗了匹配的前导部分,使得后面的输入不匹配。
我已经尝试环顾四周,但似乎无法让它发挥作用。
注意:我对涉及循环或代码等的解决方案不感兴趣。只是寻找适用于提到的边缘情况的正则表达式和替换字符串。
最佳答案
这个怎么样:
String adjacent =
"fooaXbXdbar".replaceAll(".*?(.)X(?:(?=(.)X)|(.).*?(?=.X|$))", "$1$2$3");
?
它的作用是,在 X
之后,它首先检查其后面是否紧跟着 .X
,在这种情况下,它会捕获 .
为 $2
并认为匹配完成;如果它发现没有紧接着.X
,它会继续使用您已经使用的相同逻辑,将后续字符捕获为$3
.
(注意:我已经用您的两个示例对此进行了测试,但显然它可能会错过您需要支持的其他情况。我建议您也自己测试一下。)
关于java - 是否可以对非捕获组进行反向引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13215206/