我试图查找具有特定属性/文本(作为组捕获)的锚(<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组(由正则表达式中的括号指定)。
答案 0 :(得分:3)
正则表达式默认为贪婪,因此.*
将匹配尽可能多的字符。您应该使用.*?
作为非贪婪模式。
答案 1 :(得分:2)
正如user4098326所述,问题在于贪婪。由于您使用了大量.+
组,因此它们会占用尽可能多的字符,直到字符串结束。
<a\s+.*
(更具体的是.*
)会占用所有字符,直到attr1="myattr"
的最后一次出现。然后,字符串的其余部分将完成表达式的其余部分。
答案 2 :(得分:1)
Regex is not best tool for parsing HTML。容易犯错的事情(比如使用贪婪的.*
而不是不情愿的.*?
)只是我们应该避免将正则表达式与XML / HTML混合的一小部分原因。
'
而不是"
包围,会怎样?document.write("<a attr1='foo' attr2='bar'>text</a><br/>")
有许多更好的理由可以避免使用正则表达式和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
--------------