Java 与 Javascript 正则表达式问题

标签 java regex

我的正则表达式有问题:<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/

相关文章:

java - 转换来自 Blobstore 的图像

Java:如何在覆盖已弃用成员的派生接口(interface)中避免弃用警告?

java - 为什么我的异常处理错误会导致无限循环?

java - 方法的集中职责

c++ - 使用正则表达式和 Visual Studio 查找和替换窗口计算 IDL 文件中的注释

regex - 我如何知道 Perl 正则表达式的哪一部分与字符串匹配?

Java 正则表达式转义序列

java - 以编程方式更改应用程序资源语言后,SlidingTabLayout 的选项卡语言不会更改

regex - 如何使用 R 或命令行提取与文本文件中的电子邮件地址匹配的表达式?

python - Python 中的正则表达式反向引用问题