java:我有一个很大的html字符串,需要提取href=“…”文本

yquaqz18  于 2021-06-30  发布在  Java
关注(0)|答案(7)|浏览(345)

我有一个包含大量html的字符串,正在尝试从该字符串的href=“…”部分提取链接。href可以是以下形式之一:

<a href="..." />
<a class="..." href="..." />

我对regex并没有什么问题,但出于某种原因,当我使用以下代码时:

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。。。我正在调查,但如果知道这个案子出了什么问题也会很有趣。。。

ct2axkht

ct2axkht1#

"href=\"(.*?)\"" 应该也行,但我认为库格尔的答案会更快。

aamkag61

aamkag612#

您发布的代码有两个问题:
首先是 .* 在正则表达式中是贪婪的。这将导致它匹配所有字符,直到最后一个 " 可以找到的字符。您可以通过将此更改为 .*? .
其次,要获取所有匹配项,您需要使用 Matcher.find 而不是寻找群体。组允许您访问正则表达式的每个带圆括号的部分。但是,您要查找每次整个正则表达式匹配的时间。
将这些代码放在一起可以得到以下代码,这些代码可以满足您的需要:

Pattern p = Pattern.compile("href=\"(.*?)\"", Pattern.DOTALL);
Matcher m = p.matcher(innerHTML);

while (m.find()) 
{
    System.out.println(m.group(1));
}
lyr7nygr

lyr7nygr3#

.*

这是一个贪婪的操作,它将接受包括引号在内的任何字符。
尝试以下操作:

"href=\"([^\"]*)\""
ua4mk5z4

ua4mk5z44#

您可以使用html解析器库。例如,jtidy为您提供了一个html的dom模型,您可以从中提取所有“a”元素并读取它们的“href”属性

qpgpyjmq

qpgpyjmq5#

另一种简单可靠的方法是使用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"));
}
hgc7kmma

hgc7kmma6#

regex是很好的工具,但是对于这个特殊的目的来说,它不是合适的工具。通常,您需要使用基于堆栈的解析器来实现这一点。看看javahtml解析器api的jtidy。

y53ybaqx

y53ybaqx7#

使用内置解析器。比如:

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

读者可以是一个stringreader。

相关问题