我正在尝试创建一个与replaceAll()
一起使用的正则表达式/替换对,它将捕获目标字符串之前和之后的字符。
这是我的版本,适用于简单的情况:
String adjacent = "fooaXbcXdbar".replaceAll(".*?(.)X(.).*?(?=(.X)|$)", "$1$2");
根据需要生成"abcd"
(最后的结果是消耗到字符串的结尾,使得对replaceAll()
的单个调用工作。)
然而,当目标之后的角色也是目标之前的角色时,我似乎无法解决一个边缘情况:
String adjacent = "fooaXbXdbar".replaceAll(".*?(.)X(.).*?(?=(.X)|$)", "$1$2");
生成"ab"
,但我希望"abbd"
。正则表达式消耗了匹配的前导部分,使得以下输入不匹配。
我试过环顾四周,但似乎无法让它发挥作用。
注意:我对涉及循环或代码等的解决方案不感兴趣。只是寻找适用于所提到的边缘情况的正则表达式和替换字符串。
答案 0 :(得分:2)
这个怎么样:
String adjacent =
"fooaXbXdbar".replaceAll(".*?(.)X(?:(?=(.)X)|(.).*?(?=.X|$))", "$1$2$3");
它的作用是,在X
之后,它首先检查它是否紧跟.X
,在这种情况下,它会将.
捕获为$2
并且认为比赛完成;如果它发现不后面紧跟.X
,它继续使用您已经使用的相同逻辑,将后续字符捕获为$3
。
(注意:我已经用你的两个例子对它进行了测试,但显然它可能会遗漏你需要支持的其他情况。我建议你自己测试一下。)