我有一个包含大量html的字符串,我试图从字符串的href =“...”部分中提取链接。 href可以采用以下形式之一:
<a href="..." />
<a class="..." href="..." />
我真的没有正则表达式的问题,但出于某种原因我使用以下代码:
String innerHTML = getHTML();
Pattern p = Pattern.compile("href=\"(.*)\"", Pattern.DOTALL);
Matcher m = p.matcher(innerHTML);
if (m.find()) {
// Get all groups for this match
for (int i=0; i<=m.groupCount(); i++) {
String groupStr = m.group(i);
System.out.println(groupStr);
}
}
有人可以告诉我我的代码有什么问题吗?我在PHP中做了这些东西,但在Java中,我在某种程度上做错了什么...当我尝试打印时,它会打印整个html字符串......
编辑:这样每个人都知道我正在处理的是什么类型的字符串:
<a class="Wrap" href="item.php?id=43241"><input type="button">
<span class="chevron"></span>
</a>
<div class="menu"></div>
每当我运行代码时,它会打印整个字符串......这就是问题...
关于使用jTidy ......我正在使用它,但知道在这种情况下出了什么问题会很有趣......
答案 0 :(得分:8)
.*
这是一个贪婪的操作,它将包含任何字符,包括引号。
尝试类似:
"href=\"([^\"]*)\""
答案 1 :(得分:6)
您发布的代码存在两个问题:
首先,正则表达式中的.*
是贪婪的。这将使其匹配所有字符,直到找到可以找到的最后一个"
字符。您可以将此匹配更改为.*?
。
其次,要获取所有匹配项,您需要继续使用Matcher.find
进行迭代,而不是寻找组。通过组,您可以访问正则表达式的每个带括号的部分。但是,您每次都要查找整个正则表达式。
将这些放在一起会为您提供以下代码,这些代码可以满足您的需求:
Pattern p = Pattern.compile("href=\"(.*?)\"", Pattern.DOTALL);
Matcher m = p.matcher(innerHTML);
while (m.find())
{
System.out.println(m.group(1));
}
答案 2 :(得分:5)
正则表达式很棒但不适合此特定目的。通常,您希望使用基于堆栈的解析器。看看Java HTML解析器API就像jTidy。
答案 3 :(得分:5)
使用内置解析器。类似的东西:
EditorKit kit = new HTMLEditorKit();
HTMLDocument doc = (HTMLDocument)kit.createDefaultDocument();
doc.putProperty("IgnoreCharsetDirective", Boolean.TRUE);
kit.read(reader, doc, 0);
HTMLDocument.Iterator it = doc.getIterator(HTML.Tag.A);
while (it.isValid())
{
SimpleAttributeSet s = (SimpleAttributeSet)it.getAttributes();
String href = (String)s.getAttribute(HTML.Attribute.HREF);
System.out.println( href );
it.next();
}
或者使用ParserCallback:
import java.io.*;
import java.net.*;
import javax.swing.text.*;
import javax.swing.text.html.parser.*;
import javax.swing.text.html.*;
public class ParserCallbackText extends HTMLEditorKit.ParserCallback
{
public void handleStartTag(HTML.Tag tag, MutableAttributeSet a, int pos)
{
if (tag.equals(HTML.Tag.A))
{
String href = (String)a.getAttribute(HTML.Attribute.HREF);
System.out.println(href);
}
}
public static void main(String[] args)
throws Exception
{
Reader reader = getReader(args[0]);
ParserCallbackText parser = new ParserCallbackText();
new ParserDelegator().parse(reader, parser, true);
}
static Reader getReader(String uri)
throws IOException
{
// Retrieve from Internet.
if (uri.startsWith("http:"))
{
URLConnection conn = new URL(uri).openConnection();
return new InputStreamReader(conn.getInputStream());
}
// Retrieve from file.
else
{
return new FileReader(uri);
}
}
}
Reader可以是StringReader。
答案 4 :(得分:4)
另一种简单可靠的方法是使用Jsoup
Document doc = Jsoup.connect("http://example.com/").get();
Elements links = doc.select("a[href]");
for (Element link : links){
System.out.println(link.attr("abs:href"));
}
答案 5 :(得分:2)
您可以使用html解析器库。 jtidy例如为您提供了html的DOM模型,您可以从中提取所有“a”元素并阅读其“href”属性
答案 6 :(得分:1)
"href=\"(.*?)\""
也应该有效,但我认为Kugel的答案会更快。