2013-03-25 94 views
1

我使用正则表达式从网页获取URL。Php正则表达式在不同的服务器上工作不同

在本地主机(PHP 5.3.15用了Suhosin贴片(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日2时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 
    ) 

问题是什么?

+2

,以消除任何外部缓存问题,获取URL的内容,保存到一个文件,并上传到同一目录作为你的代码,调整您的file_get_contents,并且每台服务器上运行相同的代码和相同的数据文件 – Uberfuzzy 2013-03-25 22:55:34

回答

0

我没有确切的答案。但在你的问题中,你提到你使用PHP 5.3.3和PHP 5.3.15有不同的结果。

我看了一下PHP5 ChangeLog,答案可能在于,并看到以下可能的解释。

捆绑升级PCRE到8.11版本。 (IIIa)的

升级捆绑PCRE到8.12版本。 (斯科特)

我阅读发行说明两个PCRE版本,我不知道什么会影响你的情况相匹配,除少数更正提UTF8编码。

但是,一边看着U修改我注意到PCRE Configuration Options是:

PCRE的回溯限制。默认为100000 PHP < 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

我想出了一个解决方法。如果你打开页面,去掉标签,然后解析你应该得到更一致的答案。来自微软应用程序(目标网页)的代码非常糟糕。

<?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>"; 
?> 
+0

这解决了我的问题,谢谢! – Herfox 2013-03-27 21:15:44