2009-04-30 54 views
1

我的正則表達式存在問題:<a.*href=[\"'](.*?)[\"'].*>(.*?)</a>。正如您可能知道的那樣,應該從HTML字符串中獲取所有鏈接,並返回組2中的鏈接文本以及組1中的鏈接目標。但是,我遇到了問題。如果我嘗試在Javascript(使用http://www.regextester.com/,所有的旗幟上),它工作正常,但在Java中,像這樣的:Java vs Javascript正則表達式問題

Pattern myPattern = Pattern.compile("<a.*href=[\"'](.*?)[\"'].*>(.*?)</a>", Pattern.CASE_INSENSITIVE); 
Matcher match = myPattern.matcher(htmlData); 
while(match.find()) { 
String linkText = match.group(2); 
String linkTarget = match.group(1); 
} 

我沒有得到我所期望的所有比賽。使用正則表達式測試程序,我可以獲得更多,它的工作原理與它應有的完全相同,但對於Java版本,它每頁只能獲得1或2個鏈接。
對不起,如果這是顯而易見的,但我是新的正則表達式。
謝謝,
艾薩克·沃勒

編輯:我想這可能是壞了我的正則表達式。見,從這個阿帕奇的indexOf頁:

<tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="Bryan%20Adams%20-%20Here%20I%20Am.mp3">Bryan Adams - Here I Am.mp3</a></td><td align="right">27-Aug-2008 11:48 </td><td align="right">170K</td></tr> 
<tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="Cars%20-%20Drive.mp3">Cars - Drive.mp3</a></td><td align="right">26-Aug-2008 19:04 </td><td align="right">149K</td></tr> 
<tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="Cock%20Robin%20-%20When%20Your%20Heart%20Is%20Weak.mp3">Cock Robin - When Your Heart Is Weak.mp3</a></td><td align="right">26-Aug-2008 19:04 </td><td align="right">124K</td></tr> 
<tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="Colbie%20Caillat%20-%20Bubbly.mp3">Colbie Caillat - Bubbly.mp3</a></td><td align="right">27-Aug-2008 11:49 </td><td align="right">215K</td></tr> 

<tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="Colbie%20Caillat%20-%20The%20Little%20Things.mp3">Colbie Caillat - The Little Things.mp3</a></td><td align="right">27-Aug-2008 11:49 </td><td align="right">176K</td></tr> 
<tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="Coldplay%20-%20Violet%20Hill.mp3">Coldplay - Violet Hill.mp3</a></td><td align="right">27-Aug-2008 11:49 </td><td align="right">136K</td></tr> 
<tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="Corrs%20-%20Radio.mp3">Corrs - Radio.mp3</a></td><td align="right">26-Aug-2008 19:04 </td><td align="right">112K</td></tr> 
<tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="Corrs%20-%20What%20Can%20I%20Do.mp3">Corrs - What Can I Do.mp3</a></td><td align="right">26-Aug-2008 19:04 </td><td align="right">146K</td></tr> 
<tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="Counting%20Crows%20-%20Big%20Yellow%20Taxi.mp3">Counting Crows - Big Yellow Taxi.mp3</a></td><td align="right">26-Aug-2008 19:04 </td><td align="right">135K</td></tr> 

<tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="Curtis%20Stigers%20-%20I%20Wonder%20Why.mp3">Curtis Stigers - I Wonder Why.mp3</a></td><td align="right">26-Aug-2008 19:03 </td><td align="right">213K</td></tr> 
<tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="Cyndi%20Lauper%20-%20Time%20After%20Time.mp3">Cyndi Lauper - Time After Time.mp3</a></td><td align="right">26-Aug-2008 19:03 </td><td align="right">193K</td></tr> 
<tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="David%20Bowie%20-%20Absolute%20Beginners.mp3">David Bowie - Absolute Beginners.mp3</a></td><td align="right">26-Aug-2008 19:04 </td><td align="right">155K</td></tr> 
<tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="Depeche%20Mode%20-%20Enjoy%20The%20Silence.mp3">Depeche Mode - Enjoy The Silence.mp3</a></td><td align="right">26-Aug-2008 19:03 </td><td align="right">230K</td></tr> 
<tr><td valign="top"><img src="/icons/sound2.gif" alt="[SND]"></td><td><a href="Dido%20-%20White%20Flag.mp3">Dido - White Flag.mp3</a></td><td align="right">27-Aug-2008 11:48 </td><td align="right">158K</td></tr> 

我應該得到:
1:布萊恩%20Adams%20-%20Here%20I%20Am.mp3
2:布萊恩亞當斯 - 在這裏,我Am.mp3
等等。使用正則表達式測試器,我可以獲得所有我想要的結果。用Java,我沒有收到任何東西。

+0

這不是一個Java與JavaScript的問題,只是在測試一個缺陷:它不會讓你指定單行模式(DOTALL模式在Java中)。這就是爲什麼你的正則表達式「在那裏工作」的原因:你所有的匹配都被文本中的換行符所包圍,所以他們永遠不能匹配多個鏈接。 – 2009-05-01 04:54:17

+0

謝謝Alex,我會如何解決這個問題? – 2009-05-01 22:54:21

回答

3

你必須逃離反斜槓字符和引號:

Pattern myPattern = Pattern.compile("<a.*href=[\\\"'](.*?)[\\\"'].*>(.*?)</a>", Pattern.CASE_INSENSITIVE); 

然而,這可能不是你真正的問題。模式中並不需要反斜槓。該模式還有其他一些可能的問題。

您正在使用href屬性,這意味着它會從上線到上線的最後一個環節的href屬性中的第一個環節開始比賽前一個貪婪的匹配。將它從「.*」更改爲「.*?」,使比賽非貪婪。 href屬性之後的匹配也是一樣,它必須是非貪婪的,否則它將匹配到行上最後一個鏈接的末尾。

.字符與換行符不匹配,因此如果鏈接代碼或鏈接文本中存在換行符,鏈接將不匹配。您可以使用[\W\w]而不是.來匹配任何字符。

所以,去掉反斜槓,使得比賽非貪婪和允許換行符會使模式:

Pattern myPattern = Pattern.compile("<a[\\W\\w]*?href=[\"'](.*?)[\"'][\\W\\w]*?>([\\W\\w]*?)</a>", Pattern.CASE_INSENSITIVE); 

編輯:
我忘了逃走的字符串中[\W\w]碼反斜線。

0

不要全部的全站/通配符匹配需要是不明確的嗎?

<a.*?href=[\"'](.*?)[\"'].*?>(.*?)</a> 

我不是一個Java開發人員,所以我不知道模式的轉義規則。