Java正则表达式 - 重叠匹配

时间:2013-07-31 13:15:19

标签: java regex

在以下代码中:

public static void main(String[] args) {
    List<String> allMatches = new ArrayList<String>();
    Matcher m = Pattern.compile("\\d+\\D+\\d+").matcher("2abc3abc4abc5");
    while (m.find()) {
        allMatches.add(m.group());
    }

    String[] res = allMatches.toArray(new String[0]);
    System.out.println(Arrays.toString(res));
}

结果是:

[2abc3, 4abc5]

我希望它是

[2abc3, 3abc4, 4abc5]

如何实现?

3 个答案:

答案 0 :(得分:16)

不确定这是否可以在Java中使用,但在PCRE中您可以执行以下操作:
(?=(\d+\D+\d+)).

<强>解释
该技术是在先行中使用匹配组,然后“吃掉”一个字符向前移动。

  • (?=:开始积极前瞻
    • (:开始匹配第1组
      • \d+:匹配数字一次或多次
      • \D+:匹配非数字字符一次或多次
      • \d+:匹配数字一次或多次
    • ):第1组结束
  • ):前瞻
  • .:匹配任何内容,这是“前进”。

Online demo


感谢Casimir et Hippolyte它似乎真的在Java中运行。您只需添加反斜杠并显示第一个捕获组:(?=(\\d+\\D+\\d+)).。 在www.regexplanet.com上测试:

enter image description here

答案 1 :(得分:16)

让匹配器尝试从后者\d+开始下一次扫描。

Matcher m = Pattern.compile("\\d+\\D+(\\d+)").matcher("2abc3abc4abc5");
if (m.find()) {
    do {
        allMatches.add(m.group());
    } while (m.find(m.start(1)));
}

答案 2 :(得分:2)

HamZa的上述解决方案在Java中完美运行。如果您想在文本中找到特定模式,您只需要:

String regex = "\d+\D+\d+";

String updatedRegex = "(?=(" + regex + ")).";

如果regex是您要查找的模式并且要重叠,则需要在最后用(?=(" at the start and ")).围绕它。