我的正则表达式有问题:<a.*href=[\"'](.*?)[\"'].*>(.*?)</a>
。正如您可能知道的那样,它应该从 HTML 字符串中获取所有链接,并返回组 2 中的链接文本和组 1 中的链接目标。但我遇到了问题。如果我在 Javascript 中尝试(使用 http://www.regextester.com/ ,所有标志都打开),它工作正常,但在 Java 中,如下所示:
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 个链接。
抱歉,如果这很明显,但我是正则表达式的新手。
谢谢,
艾萨克·沃勒
编辑:我认为我的正则表达式可能有问题。请参阅此 Apache 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:布莱恩%20亚当斯%20-%20这里%20I%20Am.mp3
2:布莱恩·亚当斯 - Here I Am.mp3
还有很多类似的事情。使用正则表达式测试器,我得到了我想要的所有结果。对于 Java,我什么也得不到。
最佳答案
您必须转义反斜杠字符和引号:
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]
代码中的反斜杠。
关于Java 与 Javascript 正则表达式问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/809647/