Java 正则表达式 - 重叠匹配

2022-09-01 23:01:23

在下面的代码中:

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]

如何实现?


答案 1

使匹配器尝试从后者开始下一次扫描。\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

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

解释
技术是在前瞻中使用匹配组,然后“吃”一个字符以向前移动。

  • (?=:开始正面展望
    • (:开始匹配组 1
      • \d+:匹配一个数字一次或多次
      • \D+:将非数字字符匹配一次或多次
      • \d+:匹配一个数字一次或多次
    • ):第1组结束
  • ):结束的展望
  • .:匹配任何东西,这就是“前进”。

在线演示


多亏了Casimmir et Hippolyte,它似乎真的可以在Java中工作。您只需要添加反斜杠并显示第一个捕获组:。经 www.regexplanet.com 测试:(?=(\\d+\\D+\\d+)).

enter image description here