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

10

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

  1. 在我寻找的模式内部,存在一个已知的开头,然后是一个未知的字符串,我想获取该字符串直到第一次出现&为止。
  2. 在一行中有多个这些模式的出现,我想单独获取每个出现的模式。

例如,我有以下输入行:

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

我对这些字符串很感兴趣:

Screen+Refresh+Rate%7C120HZ%5EScreen+Size%7C37+in.+to+42+in.

Screen+Refresh+Rate%7C120HZ
6个回答

14

假设已知开头为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));
}

将输出:

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

请问您能否包含testString,这样我们就可以真正地尝试一下呢?(原帖中提供的testString与此代码不兼容) - gkephorus

2
如果我知道将来可能需要其他查询参数,那么最好解码并解析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());
}

输出

subCatView = true
viewItems = 25
sName = View All
filter = Screen Refresh Rate|120HZ^Screen Size|37 in. to 42 in.

1

在Java中使用正则表达式(?<=filter=\*{0,2})[^&]*[^&*]+

Pattern p = Pattern.compile("(?<=filter=\\*{0,2})[^&]*[^&*]+");
String s = "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";
Matcher m = p.matcher(s);
while (m.find()) {
    System.out.println(m.group());
}

编辑:

在正则表达式的末尾添加了[^&*]+,以防止第二个匹配中包含**

编辑2:

更改了正则表达式以使用回顾后发现。


1
在你的例子中,有时在“&”之前会有一个“**”。但基本上,(假设“filter=”是你要查找的起始模式),你想要像这样的东西:"filter=([^&]+)&"

我看到正向前瞻正是我所需要的。谢谢! - Butter Beer

0
你需要的正则表达式是:
Screen\+Refresh\+Rate[^&]*

你可以使用 Matcher.find() 查找所有匹配项。

谢谢,但这只是一个特定的例子,适用于其他字符串。确定的是我想从filter=获取字符串,直到第一个&。 - Amit

0

你是否在寻找一个以 "filter=" 结尾且忽略第一个 "*" 的字符串,并以第一个 "&" 结尾。

你可以尝试以下代码:

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));
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接