正则表达式匹配两个连续的字符,除非后面跟着/前面有更多相同的字符

时间:2017-08-22 21:28:01

标签: java regex

我有一个如下所示的字符串:qqq Eqq Eqqq Cqq Eqq Fq。我想用qq替换所有有两个连续字符的序列(在本例中为h),所需的输出如下所示:qqq Eh Eqqq Ch Eh Fq

但是,我不希望正则表达式匹配超过两个q(qqqqqqq)的序列,并使字符串看起来像这样:hq Eh Ehq Ch Eh Fq。我已经尝试了以下但是这导致了我不想要的输出。

text = "qqq Eqq Eqqq Cqq Eqq Fq";
text = text.replaceAll("[q]{2}", "h");

我也尝试过只替换q后跟一个空格字符,但这最终会匹配每个单词中的最后两个q。有没有办法替换两个连续的字符,除非后面跟着同一个字符的第三个或第四个字符?如果有帮助,那么语言就是Java。

2 个答案:

答案 0 :(得分:5)

您可以使用基于环视的正则表达式:

String text = "qqq Eqq Eqqq Cqq Eqq Fq";
text = text.replaceAll("(?<!q)q{2}", "h");
System.out.println(text);
// => hq Eh Ehq Ch Eh Fq

请参阅Java demoregex demo

<强>详情

  • (?<!q) - 如果当前位置左侧有q,则会导致匹配失败的负面反馈
  • q{2} - 2 q个字符。

注意:如果您打算仅替换未被q包围的2个q字符,请在结尾添加否定前瞻(?!q)"(?<!q)q{2}(?!q)"

答案 1 :(得分:1)

如果你想匹配任何角色而不是特定的角色,你必须使用一些非常复杂的东西,因为Java的正则表达式不支持variable-length look-behind。我想出了这个:

(?!([a-z])\1\1)(.)([a-z])\3(?!\3)

<强>解释

(?!            # negative look-ahead
  ([a-z])\1\1  # [group 1] match a letter and 2 more of the same letter
)              # end of the negative look-ahead
(.)            # [group 2] match any character - this is for some other character 
               # before what you want ('E', 'C', or 'F' in your examples)
               # this will not match the repeated character -
               # guaranteed by the previous negative look-ahead
([a-z])        # [group 3] the letter to be replaced
\3             # the same letter (reference to the previous group)
(?!\3)         # negative look-ahead - 
               # makes the pattern not match more than 2 of the same character

您必须替换$2h(模式中$2(.)

Java demoregex101 demo