从Snoopy类中提取函数:获取链接标签
通分析过了Snoopy类,它里面有比较完善的匹配源码,可以看到有function fetchlinks($URI)。也就是获取”< a >”中链接的函数,可以很简单的提取出来,此外还发现,它的正则还支持高级语言中的三目运算,函数及示例如下:
1<?php
2function _striplinks($document) {
3 preg_match_all("'<s*as.*?hrefs*=s*(["'])?(?(1) (.*?)\1 | ([^s>]+))'isx", $document, $links);
4 // catenate the non-empty matches from the conditional subpattern
5 while (list($key, $val) = each($links[2])) {
6 if (!empty($val))
7 $match[] = $val;
8 } while (list($key, $val) = each($links[3])) {
9 if (!empty($val))
10 $match[] = $val;
11 }
12 // return the links
13 return $match;
14}
15$document = file_get_contents('http://www.qq.com');
16$datalink = _striplinks($document);
17printf("<p>输出link数据为:</p>%sn", var_export($datalink , true));
18?>
以上函数及例子中对源码去掉了注释,通过执行发现很容易就得到了链接部分。下面对上面的正则部分做下解析:
1正则分析:`]+))`'
2
3(\["'\])? # 匹配单引或双引号为分组1,也可以没有
4(?(1) (.\*?)\\1 | (\[^s>\]+)) # 如果引号存在(分组1存在)匹配后引号否则匹配非空格和非>内容
这个正则的难点也就是 (xxx)? (?(分组号) yyy|zzz)
我也是第一次碰到这样的正则,有点像高级语言的三目运算,我举个例子:
这个例子的目的是查找符合以下的规则
1、以123开头
2、后面有双引号则匹配引号和引号内的内容。
3、后面没有双引号,则是匹配后面为789的内容。
简单来说是匹配123″……” 或 123789
有引号优先匹配
1<?php
2$str = '123"456"789';
3$search = '/123(")?(?(1).*?\1|789)/';
4preg_match($search,$str,$r);
5echo $r[0];
6//output 123"456"
7echo '<br /><br />';
8$str = '123456789';
9$search = '/123(")?(?(1).*?\1|789)/';
10preg_match($search,$str,$r);
11echo $r[0];
12//output NULL
13echo '<br /><br />';
14$str = '123789456';
15$search = '/123(")?(?(1).*?\1|789)/';
16preg_match($search,$str,$r);
17echo $r[0];
18//output 123789
19?>
从以上示例可以看到,
格式就像三目运算,高级语言是这样的:
(xxx)? yyy : zzz 如果xxx为真 执行yyy,否则执行zzzz
在正则中是:
(xxx)? (?(分组号) yyy|zzz) 如果xxx不为空 执行yyy,否则执行zzzz
捐赠本站(Donate)
如您感觉文章有用,可扫码捐赠本站!(If the article useful, you can scan the QR code to donate))
- Author: shisekong
- Link: https://blog.361way.com/php-snoopy/2774.html
- License: This work is under a 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. Kindly fulfill the requirements of the aforementioned License when adapting or creating a derivative of this work.