2009-11-15 60 views
1

我会第一个承认我的正则表达式知识是无望的。我使用的Java与下列正则表达式来提取链接内容

Matcher m = Pattern.compile(">[^<>]*</a>").matcher(html); 
while (m.find()) { 
resp.getWriter().println(html.substring(m.start(), m.end())); 
} 

我得到以下列表:

>Link Text a</a> 
>Link Text b</a> 

我缺少的是去除></a>

干杯。

+0

@Littlejon - 正则表达式+ HTML的问题是不是很受追捧。 (顺便说一句,我不是在这中间又获得......前一个是我最downvoted答案永远。http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml -self-contained-tags) – Kobi 2009-11-15 09:55:56

+0

@Kobi - 所以我见过。但我只搜索HTML片段。也尝试使用DOM没有太大的成功。 – Littlejon 2009-11-15 09:58:09

+2

作为一个附录,我完全意识到了这些限制,并且准备好将自己的脚指向一个加载枪:-) – Littlejon 2009-11-15 10:04:16

回答

2

你可以做,通过包装一组在你的正则表达式的一部分,然后用group(X)其中X是组数量:

Matcher m = Pattern.compile(">([^<>]*)</a>").matcher(html); 
while (m.find()) { 
resp.getWriter().println(m.group(1)); 
} 

但是,更好的方法是使用一个简单的解析器为此:

import java.io.*; 
import javax.swing.text.*; 
import javax.swing.text.html.*; 
import javax.swing.text.html.parser.*; 

public class HtmlParseDemo { 
    public static void main(String [] args) throws Exception { 
     Reader reader = new StringReader("foo <a href=\"#\">Link 1</a> bar <a href=\"#\">Link <b>2</b> more</a> baz"); 
     HTMLEditorKit.Parser parser = new ParserDelegator(); 
     parser.parse(reader, new LinkParser(), true); 
     reader.close(); 
    } 
} 

class LinkParser extends HTMLEditorKit.ParserCallback { 

    private boolean linkStarted = false; 
    private StringBuilder b = new StringBuilder(); 

    public void handleText(char[] data, int pos) { 
     if(linkStarted) b.append(new String(data)); 
    } 

    public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) { 
     if(t == HTML.Tag.A) linkStarted = true; 
    } 

    public void handleEndTag(HTML.Tag t, int pos) { 
     if(t == HTML.Tag.A) { 
      linkStarted = false; 
      System.out.println(b); 
      b = new StringBuilder(); 
     } 
    } 
} 

输出:

Link 1 
Link 2 more 
+0

这很好。谢谢。 – Littlejon 2009-11-15 10:09:40

+0

不客气Littlejon。 – 2009-11-15 10:30:30

+0

我可以找到链接,即'#'而不是链接1或链接2? – Rites 2010-01-13 09:30:42

2

您是否看过使用capturing group

Pattern.compile(">([^<>]*)</a>") 

然而要注意它通常是不建议用于HTML正则表达式,因为HTML是不正规。您将通过使用HTML解析器(如JTidy)获得更可靠的结果。

+0

我试过这个。提供相同的列表。干杯。 – Littlejon 2009-11-15 09:59:04

+0

这个答案也是正确的。将html.substring(m.start(),m.end())更改为m.group(1)可以实现此功能。 – Littlejon 2009-11-15 10:12:00

2

请记住,由于其有限性,您正则表达式(正则表达式和一般)可能会遇到的问题,如果你试图解析HTML稍微复杂一些。例如,下面将不能正确解析,但完全是有效的(普通)HTML:

<a href="blah.html">this is only a <em>single</em> link</a> 

你可能会更好使用DOM解析器(我敢肯定,Java有大量的选项,在此关注)您可以请求每个<a>标签的内文。

+1

不,它不会失败,它只是不会给你你期望的;;)“>链接” – falstro 2009-11-15 09:59:30

1

我迟到了,但我想指出的另一种选择:如果你把你的初始>成一团糟,即

(?<=>)[^<>]*</a> 

那么它不应该退还

(?<=X)  X, via zero-width positive lookbehind 

作为你结果的一部分。

虽然未经测试。祝你好运!