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

Java正则提取分组多次匹配结果,解决分组覆盖丢失问题

解决Java正则重复捕获组丢失内容的问题

问题根源

你遇到的问题是Java正则中重复捕获组仅保留最后一次匹配结果:原正则里的(?:,<np>([\\w]+)\\s)*是重复分组,每次匹配都会覆盖该分组的内容,最终只能拿到最后一个匹配的bop,前面的mip、bip被直接覆盖丢失。

解决方案

要捕获数量未知的<np>元素,不能依赖单个正则的重复分组,需拆分两步处理:

  1. 先匹配出"such as"前后的核心片段;
  2. 对"such as"后的片段单独遍历,逐个提取每个<np>内的内容。

修改后的代码实现

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Detector {
    private final String input;
    private final String mainPattern;
    private final String lemma;
    private final Map<Integer, String> groups;

    public Detector(String input, String mainPattern, String lemma) {
        this.input = input;
        this.mainPattern = mainPattern;
        this.lemma = lemma;
        this.groups = new HashMap<>();
        processInput();
    }

    public void processInput() {
        // 第一步:匹配"such as"前的主体和后面的所有<np>片段
        Pattern mainRegex = Pattern.compile(mainPattern);
        Matcher mainMatcher = mainRegex.matcher(input);

        int groupIndex = 1;
        if (mainMatcher.find()) {
            // 存入"such as"前的内容
            groups.put(groupIndex++, mainMatcher.group(1));
            // 提取"such as"后的完整片段
            String npSection = mainMatcher.group(2);
            
            // 第二步:逐个匹配每个<np>内的文本
            Pattern npRegex = Pattern.compile("&lt;np&gt;([\\w]+)");
            Matcher npMatcher = npRegex.matcher(npSection);
            
            while (npMatcher.find()) {
                groups.put(groupIndex++, npMatcher.group(1));
            }
        }

        System.out.println(groups);
    }

    public static void main(String[] args) {
        String input = "&lt;np&gt;semitic languages such as &lt;np&gt;Hebrew ,&lt;np&gt;mip ,&lt;np&gt;bip ,&lt;np&gt;bop or &lt;np&gt;Arabic";
        // 主正则简化为匹配前后两部分
        String mainPattern = "&lt;np&gt;,?([\\w\\s]+)\\s+such as\\s+(.*)";
        Detector suchAs = new Detector(input, mainPattern, "mip");
    }
}

代码说明

  1. 主正则调整:将原复杂正则拆分为&lt;np&gt;,?([\\w\\s]+)\\s+such as\\s+(.*),第一组捕获"such as"前的内容,第二组捕获后续所有包含<np>的片段;
  2. 子正则遍历:用&lt;np&gt;([\\w]+)作为子正则,通过while (npMatcher.find())循环逐个提取每个<np>内的文本,彻底避免重复分组覆盖的问题;
  3. 结果存储:按顺序将所有捕获内容存入groups,确保没有遗漏。

运行结果

执行后输出:{1=semitic languages, 2=Hebrew, 3=mip, 4=bip, 5=bop, 6=Arabic},所有<np>元素均被正确捕获。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 05:00:35