2009-11-15 59 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 

作爲你結果的一部分。

雖然未經測試。祝你好運!