从Java中的HTML标记属性中提取值

时间:2012-01-09 17:51:01

标签: java regex

我最近接受了社区挑战,我试图在以下行中提取'rel'标记的值:

<td><a title='Visit Personal Stats Page for ijackk' href='personal.php?name=ijackk&amp;clan=ph_chat_ftw' class='rsn' rel='ijackk' style='color: #FFFFFF;'>ijackk</a></td>

原因是挑战要求我从成员列表中提取多个用​​户的名称(具有与其帐户相关属性的人员列表)。我不 HAVE 使用正则表达式,但我觉得它会是最好的。我已经看过为什么正则表达式很糟糕的经典帖子,但我也看过帖子说用它来做类似的东西并不是坏事。

以下是我到目前为止所做的事情:

public class Parser {

public static void main(String[] arguments) {
    new Parser().parse();
}

public void parse() {
    try {
        URL url = new URL("http://www.runehead.com/clans/ml.php?clan=ph_chat_ftw");
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
        String line;
        StringBuilder stringBuilder = new StringBuilder();
        while ((line = bufferedReader.readLine()) != null) {
            if (line.contains("Visit")) {
                stringBuilder.append(line).append("\n");
                System.out.println(line);
            }
        }
        Matcher matcher = Pattern.compile("\\?rel='([A-Za-z0-9_]*)'").matcher(stringBuilder.toString());
        while (matcher.find()) {
            System.out.println("matched: " + matcher.group(1));
        }
    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

}

我所拥有的输出是我上面提供的,除了每个名字。但是,匹配器找不到任何东西。我能得到一些帮助吗?

3 个答案:

答案 0 :(得分:2)

使用正确的HTML解析库。我更喜欢jSoup,但还有很多其他人。

在大多数情况下,使用RegEx来解析HTML要比它的价值更加痛苦。首先不仅难以做到,而且工作的任何事情都可能如此令人费解,以至于它基本上是完全无法维护的。


Here's an example使用jSoup获取rel属性:

String html = "<p>An <a href='http://example.com/' rel='someValue'><b>example</b></a> link.</p>";
Document doc = Jsoup.parse(html);
Element link = doc.select("a").first();

String text = doc.body().text(); // "An example link"
String linkRel = link.attr("rel"); // "someValue"

答案 1 :(得分:2)

正则表达式和HTML结合起来就是在这里发誓。正则表达式在解析非常规标记(如HTML或XML)时效果不佳。

使用HTML解析器库执行此操作可能会更好。似乎有人在这里恰当地命名为HTML Parser library

编辑: - 或者jSoup也可以工作。那里有很多选择!

答案 2 :(得分:2)

您假设rel属性紧跟?之后,但情况并非如此。您可以使用以下内容:

Pattern.compile("rel=\"([A-Za-z0-9_]*)\"")

这当然有效,但正如其他人所说,你最好使用合适的HTML解析器。这是一个jsoup示例:

Document doc = Jsoup.connect(
    "http://www.runehead.com/clans/ml.php?clan=ph_chat_ftw").get();
Elements users = doc.select("a[rel]");
for (Element user : users) {
    System.out.println(user.attr("rel"));
}

与正则表达式方法相比,它更清晰(更安全(更灵活(也更易于维护)))。