正则表达式解析包含特定单词的链接

时间:2010-02-01 08:11:03

标签: php regex parsing

this线程更进一步,有人能告诉我这两个正则表达式之间有什么区别吗?他们似乎都做了同样的事情:从html中拉出一个链接。

表达式1:

'/(https?://)?(www.)?([a-zA-Z0-9_%]*)\b.[a-z]{2,4}(.[a-z]{2})?((/[a-zA-Z0-9_%])+)?(.[a-z])?/'

表达式2:

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

哪一个会更好用?我怎样才能修改其中一个表达式以仅匹配包含某些单词的链接,并忽略任何不包含这些单词的匹配?

感谢。

4 个答案:

答案 0 :(得分:3)

区别在于表达式1遵循规范查找有效和完整的URI。因此,您将获得代码内部的所有完整URL。这与获取所有链接并不真正相关,因为它与经常使用的相对URL不匹配,并且它获取每个URL,而不仅仅是链接目标的URL。

第二个查找a代码并获取href属性的内容。所以这个会给你带来每个环节。除了该表达式中的一个错误*之外,使用它是非常安全的,并且它将足以使您获得每个链接 - 它会检查可能出现的足够差异,例如空格或其他属性。

*但是该表达式中有一个错误,因为它没有查找href属性的结束引用,您应该添加它,或者您可能匹配奇怪的东西:

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

编辑以回复评论:

要查找链接网址内的word,请使用:

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

要在链接文本中查找word,请使用:

/<a.*?href\s*=\s*["\']([^"\'>]+)["\'][^>]*>.*?word.*?<\/a>/si

答案 1 :(得分:1)

在大多数情况下,我强烈建议使用HTML解析器(例如this one)来获取这些链接。使用正则表达式来解析HTML将会有问题,因为HTML不是常规的,你不会考虑边缘情况的结束。

有关详细信息,请参阅here

答案 2 :(得分:1)

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

你必须非常小心.*,即使是非贪婪的形式。 .容易匹配比你讨价还价更多,特别是在dotall模式下。例如:

<a name="foo">anchor</a>
<a href="...">...</a>

从第一个<a的开头到第二个结尾的匹配。

更不用说像:

<a href="a"></a >
<a href="b"></a>

或:

<a href="a'b>c">

或:

<a data-href="a" title="b>c" href="realhref">

或:

<!-- <a href="notreallyalink"> -->

以及更多有趣的边缘案例。您可以尝试优化正则表达式以捕获更多可能性,但是您永远不会得到它们,因为HTML无法使用正则表达式进行解析(告诉您的朋友)!

HTML +正则表达式是一个傻瓜的游戏。帮自己一个忙。使用HTML解析器。

答案 3 :(得分:0)

乍一看,第一个是垃圾,但似乎是试图将链接作为文本匹配,第二个是匹配html元素。