我正在使用正则表达式从网页上获取网址。
在localhost上(PHP 5.3.15与Suhosin-Patch(cli)(内置:2012年8月24日17:45:44))代码:
$file = file_get_contents("http://www.etech.haw-hamburg.de/Stundenplan/");
$pattern = "/<a href=\"([^\"]*.pdf)\">(.*)<\/a>/iU";
preg_match_all($pattern, $file, $matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
给出:
=> Array
(
[0] => Sem_IuE_E1a.pdf
[1] => Sem_IuE_E2a.pdf
[2] => Sem_IuE_E3a.pdf
[3] => Sem_IuE_E4a.pdf
[4] => Sem_IuE_E6AT.pdf
[5] => Sem_IuE_E7.pdf
[6] => Sem_IuE_E1b.pdf
[7] => Sem_IuE_E2b.pdf
[8] => Sem_IuE_E3b.pdf
[9] => Sem_IuE_E4b.pdf
[10] => Sem_IuE_E6II.pdf
[11] => Sem_IuE_E6KT.pdf
[12] => Sem_IuE_BMT1.pdf
[13] => Laborplan%20BMT1%20KoP%201.pdf
[14] => Sem_IuE_BMT2.pdf
[15] => Sem_IuE_BMT3.pdf
[16] => Sem_IuE_BMT4.pdf
[17] => Sem_IuE_BMT5.pdf
[18] => Sem_IuE_BMT6.pdf
[19] => Sem_IuE_IE2.pdf
[20] => Sem_IuE_IE4.pdf
[21] => Sem_IuE_IE6.pdf
[22] => Sem_IuE_AM.pdf
[23] => Sem_IuE_IKM1.pdf
[24] => Legende_Stud.pdf
[25] => Kalender.pdf
[26] => Doz.pdf
[27] => Doz.pdf
)
而在远程服务器上(PHP 5.3.3(cli)(内置:2013年2月22日02:51:11)),相同的代码给出:
=> Array
(
[0] => Sem_IuE_E2a.pdf
[1] => Sem_IuE_E7.pdf
[2] => Sem_IuE_E1b.pdf
[3] => Sem_IuE_E2b.pdf
[4] => Sem_IuE_E3b.pdf
[5] => Sem_IuE_E6II.pdf
[6] => Sem_IuE_E6KT.pdf
[7] => Sem_IuE_BMT1.pdf
[8] => Laborplan%20BMT1%20KoP%201.pdf
[9] => Sem_IuE_BMT2.pdf
[10] => Sem_IuE_BMT3.pdf
[11] => Sem_IuE_BMT4.pdf
[12] => Sem_IuE_BMT5.pdf
[13] => Sem_IuE_BMT6.pdf
[14] => Sem_IuE_IE2.pdf
[15] => Sem_IuE_IE4.pdf
[16] => Sem_IuE_IE6.pdf
[17] => Sem_IuE_AM.pdf
[18] => Doz.pdf
[19] => Doz.pdf
)
有什么问题?
答案 0 :(得分:1)
我没有确切的答案。但是在你的问题中,你提到使用PHP 5.3.3和PHP 5.3.15会得到不同的结果。
我看了PHP5 ChangeLog,答案可能就在哪里,并看到了以下可能的解释。
将捆绑的PCRE升级到版本8.11。 (IIIa)的
将捆绑的PCRE升级到版本8.12。上(Scott)
我阅读了两个PCRE版本的发行说明,我不确定在您的情况下哪些会影响匹配,除了一些提及UTF8编码的更正。
但是,在查看U
修饰符时,我在PCRE Configuration Options中注意到:
PCRE的回溯限制。 PHP&lt;默认为100000 5.3.7。
我的猜测是U
(PCRE_UNGREEDY)修饰符中的某些修正更改了<a>
之间的部分匹配方式。这是有道理的,因为通过查看您正在抓取的页面的来源,在早期PHP版本中匹配的唯一一个是不包含内部HTML的<a>
标记。
示例,这个匹配:
<a href="Sem_IuE_E2a.pdf">E2a</a>
这个没有:
<a href="Sem_IuE_E4a.pdf"><span lang=IT style='mso-ansi-language:IT'>E4a</span></a>
非常有趣,但如何解决?
我无法访问早期的PHP版本,因此我无法对其进行测试,但我会说删除正则表达式中的贪婪部分,因为您不需要匹配<a></a>
中的部分标签,因为该值已包含在PDF文件名中:
$pattern = "/<a href=\"([^\"]*.pdf)\">/i";
或强>
使用DOM Parser。
答案 1 :(得分:1)
我想出了一个解决方法。如果您打开页面,请删除标签,然后解析您应获得更一致的答案。来自Microsoft应用程序(目标页面)的代码非常糟糕。
<?php
$file = file_get_contents("http://www.etech.haw-hamburg.de/Stundenplan/");
$file = strip_tags($file,'<a>');
$pattern = "!\<a href=[\"|']([^.]+\.pdf)[\"|']\>([^\<]+)\<\/a\>!iU";
preg_match_all($pattern, $file, $matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
?>