Java正则表达式:如何在同一行中捕获多个匹配项

Java正则表达式:如何在同一行中捕获多个匹配项,java,regex,Java,Regex,我正在尝试匹配Java中的正则表达式模式,我有两个问题: 在我正在寻找的模式中,有一个已知的开始,然后是一个未知的字符串,我希望得到它,直到第一次出现& 这些模式在该行中多次出现,我希望分别获得每个出现 例如,我有以下输入行: 1234567 100110116129139140144146http://www.gold.com/shc/s/c_10153_12605_Computers+%26+电子电视?过滤器=屏幕+刷新+速率%7C120HZ%5EScreen+尺寸%7C37+至+42+英

我正在尝试匹配Java中的正则表达式模式,我有两个问题:

  • 在我正在寻找的模式中,有一个已知的开始,然后是一个未知的字符串,我希望得到它,直到第一次出现&
  • 这些模式在该行中多次出现,我希望分别获得每个出现
  • 例如,我有以下输入行:

    1234567 100110116129139140144146http://www.gold.com/shc/s/c_10153_12605_Computers+%26+电子电视?过滤器=屏幕+刷新+速率%7C120HZ%5EScreen+尺寸%7C37+至+42+英寸。&sName=视图+所有视图项=25&子视图=真实ISx20070515x00001ahttp://www.gold.com/shc/s/c_10153_12605_Computers+%26+电子电视?过滤器=屏幕+刷新+速率%7C120HZ&sName=视图+全部和子视图=真0 2819357575609397706
    
    我对这些字符串感兴趣:

    Screen+刷新+速率%7C120HZ%5EScreen+大小%7C37+英寸+至+42+英寸。
    屏幕+刷新+速率%7C120HZ
    
    您要查找的正则表达式是

    Screen\+Refresh\+Rate[^&]*
    

    您可以使用查找所有匹配项。

    在您的示例中,有时在“&”之前的末尾有一个“**”。但基本上,(假设“filter=”是您正在寻找的开始模式)您想要的是:


    “filter=([^&]+)&”
    使用正则表达式
    (?如果我知道将来可能需要其他查询参数,我认为解码和解析URL更为谨慎

    String url = URLDecoder.decode("http://www.gold.com/shc/s/c_10153_12605_" +
                "Computers+%26+Electronics_Televisions?filter=Screen+Refresh+Rate" +
                "%7C120HZ%5EScreen+Size%7C37+in.+to+42+in.&sName=View+All&viewItems=25&subCatView=true"
                ,"utf-8");
    Pattern amp = Pattern.compile("&");
    Pattern eq = Pattern.compile("=");
    Map<String, String> params = new HashMap<String, String>();
    String queryString = url.substring(url.indexOf('?') + 1);
    for(String param : amp.split(queryString)) {
        String[] pair = eq.split(param);
        params.put(pair[0], pair[1]);
    }
    for(Entry<String, String> param : params.entrySet()) {
        System.out.format("%s = %s\n", param.getKey(), param.getValue());
    }
    

    假设已知的开头是
    filter=***
    ,正则表达式模式
    (?:filter=\\\\\\\*)(.*?(:&)
    应该可以满足您的需要。使用
    Matcher.find()
    可以获取给定字符串中所有出现的模式。使用您提供的测试字符串,可以执行以下操作:

    final Pattern p = Pattern.compile("(?:filter=\\*\\*)(.*?)(?:&)");
    final Matcher m = p.matcher(testString);
    int cnt = 0;
    while (m.find()) {
        System.out.println(++cnt + ": G1: " + m.group(1));
    }
    
    String str = "1234567 100,110,116,129,139,140,144,146 http://www.gold.com/shc/s/c_10153_12605_Computers+%26+Electronics_Televisions?filter=**Screen+Refresh+Rate%7C120HZ%5EScreen+Size%7C37+in.+to+42+in.&sName=View+All**&viewItems=25&subCatView=true   ISx20070515x00001a          http://www.gold.com/shc/s/c_10153_12605_Computers+%26+Electronics_Televisions?filter=**Screen+Refresh+Rate%7C120HZ**&sName=View+All&subCatView=true 0   2819357575609397706";
        Pattern p = Pattern.compile("filter=(?:\\**)([^&]+?)(?:\\**)&");
    
        Matcher matcher = p.matcher(str);
        while(matcher.find()){
            System.out.println(matcher.group(1));
        }
    
    将输出:

    1: G1: Screen+Refresh+Rate%7C120HZ%5EScreen+Size%7C37+in.+to+42+in.
    2: G1: Screen+Refresh+Rate%7C120HZ**
    

    是否要查找后跟“filter=”并忽略第一个“*”且以第一个“&”结尾的字符串。 您可以尝试以下操作:

    final Pattern p = Pattern.compile("(?:filter=\\*\\*)(.*?)(?:&)");
    final Matcher m = p.matcher(testString);
    int cnt = 0;
    while (m.find()) {
        System.out.println(++cnt + ": G1: " + m.group(1));
    }
    
    String str = "1234567 100,110,116,129,139,140,144,146 http://www.gold.com/shc/s/c_10153_12605_Computers+%26+Electronics_Televisions?filter=**Screen+Refresh+Rate%7C120HZ%5EScreen+Size%7C37+in.+to+42+in.&sName=View+All**&viewItems=25&subCatView=true   ISx20070515x00001a          http://www.gold.com/shc/s/c_10153_12605_Computers+%26+Electronics_Televisions?filter=**Screen+Refresh+Rate%7C120HZ**&sName=View+All&subCatView=true 0   2819357575609397706";
        Pattern p = Pattern.compile("filter=(?:\\**)([^&]+?)(?:\\**)&");
    
        Matcher matcher = p.matcher(str);
        while(matcher.find()){
            System.out.println(matcher.group(1));
        }
    

    谢谢,但这是一个包含其他字符串的一般情况的特定示例。可以肯定的是,我想从filter=到first&我看到积极的前瞻性正是我所需要的。谢谢!请您包含testString,这样我们就可以真正尝试一下了?(OP中给定的testString不适用于此代码)