You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java正则匹配如何获取字符串中所有符合规则的匹配项?

问题根因

你写的代码只返回1个结果是三个写法问题共同导致的:

  • 正则交替符|是从左到右短路匹配的,你写的(ABC|ABC :)会优先命中靠左的短分支ABC,根本不会尝试匹配右侧更长的ABC :分支,不可能在一次分支判断里返回两个结果。
  • 正则末尾的.*会在命中分支后,把后续所有剩余字符串全部纳入匹配范围,单次匹配就直接消费到字符串末尾,没有机会产生第二次匹配。
  • 你调用的MatchResult::group默认取第0组也就是整个正则的完整匹配内容,就算捕获组命中多个分支也不会拆分返回。

另外补充正则匹配的默认规则:普通匹配会消费命中的字符,游标会直接移动到本次匹配的末尾位置,而你要的两个结果ABC和ABC :是前缀重叠的(ABC是ABC :的前3个字符),默认消费式匹配不可能在同一段文本上先后命中这两个重叠结果。顺带一提你原代码里的Collection.toList()是编译错误,正确的流收集写法是Collectors.toList(),需要先导入对应包。

修复方案

按下面的规则调整正则和匹配逻辑即可拿到预期结果:

  1. 删掉正则末尾无意义的.*,避免单次匹配吞掉整段后续文本
  2. 交替匹配的分支把更长的匹配项放前面,避免短分支提前短路
  3. 用正向前瞻零宽断言(?=...)包裹匹配规则,匹配时不移动游标、不消费字符,支持捕获重叠位置的匹配结果
  4. 匹配结果取第一个捕获组的内容即可,因为零宽断言的主匹配组是空字符串

调整后的可运行代码如下:

import java.util.List;
import java.util.regex.MatchResult;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class RegexTest {
    public static void main(String[] args) {
        String my_string = "This is the code ABC : xyz use for something";
        String my_regex = "(?=(ABC :|ABC))";

        List<String> matchers = Pattern.compile(my_regex, Pattern.CASE_INSENSITIVE)
                .matcher(my_string)
                .results()
                .map(matchResult -> matchResult.group(1))
                .collect(Collectors.toList());
        
        // 直接运行输出结果:[ABC :, ABC],如果需要调整顺序可以自行对列表做排序处理
        System.out.println(matchers);
    }
}

如果你不需要拿到重叠的匹配结果,只是想提取字符串中存在的所有独立目标片段,直接去掉零宽断言、保留ABC :|ABC的分支顺序即可,只是这种写法只会匹配到更长的ABC :,不会返回前缀的ABC,和你要两个结果的预期不符。

内容的提问来源于stack exchange,提问作者CodeIntro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 03:39:26