在改博客的时候遇到一个需求,需要处理网站上的所有外部链接,再自动加上ref="external nofollow"
。那么就需要使用到正则匹配,但是又怕出现漏网之鱼,需要正则能匹配到所有的A标签,最终在国外网站上找到了比较完美的正则。
1.基本正则
1 |
/<a href=\"([^\"]*)\">(.*)<\/a>/iU |
- 以
<a href="
开头 - 使用双引号
- 链接之后紧跟
">
- 中间为任意链接文字
- 最后以
</a>
结尾。
注:
- i 匹配大小写
- s 模式中的圆点元字符(.)匹配所有的字符,包括换行符
- U (PCRE_UNGREEDY) 本修正符反转了匹配数量的值使其不是默认的重复,而变成在后面跟上“?”才变得重复。这和 Perl 不兼容。也可以通过在模式之中设定 (?U) 修正符来启用此选项。
扩展,a
和herf
之间有不确定多个空格:
1 |
/<a\shref=\"([^\"]*)\">(.*)<\/a>/siU |
2.标签中包含不确定属性
1 |
/<a\s[^>]*href=\"([^\"]*)\"[^>]*>(.*)<\/a>/siU |
- 在
a
和href
、href
和>
之间有其他不确定的属性值,比如target
、style
、ref
等
3.允许不包含双引号
1 |
/<a\s[^>]*href=(\"??)([^\" >]*?)\\1[^>]*>(.*)<\/a>/siU |
4.继续优化匹配规则
1)=
之间存在空格
1 |
/<a\s[^>]*href\s*=\s*(\"??)([^\" >]*?)\\1[^>]*>(.*)<\/a>/siU |
2)只匹配以http
开头的链接
1 |
/<a\s[^>]*href=(\"??)(http[^\" >]*?)\\1[^>]*>(.*)<\/a>/siU |
3)允许单引号
1 |
/<a\s[^>]*href=([\"\']??)([^\"\' >]*?)\\1[^>]*>(.*)<\/a>/siU |
5.测试使用
1 2 3 4 5 6 7 8 9 10 11 |
<?PHP $url = "http://www.example.net/somepage.html"; $input = @file_get_contents($url) or die("Could not access file: $url"); $regexp = "<a\s[^>]*href=([\"\']??)([^\"\' >]*?)\\1[^>]*>(.*)<\/a>"; if(preg_match_all("/$regexp/siU", $input, $matches, PREG_SET_ORDER)) { foreach($matches as $match) { // $match[2] = link address // $match[3] = link text } } ?> |
链接:PHP: Parsing HTML to find Links
- 本文固定链接: https://blog.kuoruan.com/77.html
- 转载请注明: Index 于 扩软博客 发表
捐 赠如果您觉得这篇文章有用处,请支持作者!鼓励作者写出更好更多的文章!