使用Regex查找多个匹配项

时间:2015-03-28 10:55:41

标签: java regex

我试图查找具有特定属性/文本(作为组捕获)的锚(<a>)HTML标记的所有出现(可能有零个或多个)。

正则表达式<a\s+.*attr1="myattr".*attr2="(.+)".*attr3="(.+)".*>(.+)</a>

输入字符串

First <a attr1="myattr" attr2="value12" attr3="value13">text1</a> Second <a attr1="myattr" attr2="value12" attr3="value13">text1</
a> Third <a attr1="myattr" attr2="value12" attr3="value13">text1</a>

结果:它说只发现了一次。它将返回第一次出现的&#34; <a&#34;作为正确的起始索引(匹配),但它表示最后一次出现&#34; </a>&#34;作为最终指数。 预期结果:3场比赛,每场比赛3组(由正则表达式中的括号指定)。

3 个答案:

答案 0 :(得分:3)

正则表达式默认为贪婪,因此.*将匹配尽可能多的字符。您应该使用.*?作为非贪婪模式。

答案 1 :(得分:2)

正如user4098326所述,问题在于贪婪。由于您使用了大量.+组,因此它们会占用尽可能多的字符,直到字符串结束。

<a\s+.*(更具体的是.*)会占用所有字符,直到attr1="myattr"的最后一次出现。然后,字符串的其余部分将完成表达式的其余部分。

答案 2 :(得分:1)

Regex is not best tool for parsing HTML。容易犯错的事情(比如使用贪婪的.*而不是不情愿的.*?)只是我们应该避免将正则表达式与XML / HTML混合的一小部分原因。

  • 如果属性被'而不是"包围,会怎样?
  • 如果您的HTML包含document.write("<a attr1='foo' attr2='bar'>text</a><br/>")
  • 的JavaScript代码,该怎么办?
  • 如果元素在评论中怎么办?

有许多更好的理由可以避免使用正则表达式和HTML。因此,您应该考虑使用jsoup之类的正确解析器而不是正则表达式。

这样,选择包含a attr1 attr2属性的所有attr3代码的代码就像

Elements elements = doc.select("a[attr1][attr2][attr3]");

演示:

String html = "First <a attr1=\"myattr\" attr2=\"value12\" attr3=\"value13\">text1</a>"
        + " Second <a attr1=\"myattr\" attr2=\"value12\" attr3=\"value13\">text1</a>"
        + " Third <a attr1=\"myattr\" attr2=\"value12\" attr3=\"value13\">text1</a>";

Document doc = Jsoup.parse(html);
Elements elements = doc.select("a[attr1][attr2][attr3]");

for (Element el: elements){
    System.out.println(el);
    System.out.println(el.attr("attr1"));
    System.out.println(el.attr("attr2"));
    System.out.println(el.attr("attr3"));
    System.out.println(el.text());
    System.out.println("--------------");
}

输出:

<a attr1="myattr" attr2="value12" attr3="value13">text1</a>
myattr
value12
value13
text1
--------------
<a attr1="myattr" attr2="value12" attr3="value13">text1</a>
myattr
value12
value13
text1
--------------
<a attr1="myattr" attr2="value12" attr3="value13">text1</a>
myattr
value12
value13
text1
--------------