1

WebページからURLを取得するために正規表現を使用しています。

ローカルホスト (Suhosin-Patch (cli) を使用した PHP 5.3.15 (ビルド: 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
    )

何が問題ですか?

4

2 に答える 2

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>";
?>
于 2013-03-25T23:33:25.277 に答える
1

正確な答えはありません。しかし、あなたの質問では、PHP 5.3.3 と PHP 5.3.15 を使用すると異なる結果が得られると述べています。

答えがおそらくあるPHP5 ChangeLogを調べたところ、次の可能な説明がありました。

バンドルされている PCRE をバージョン 8.11 にアップグレードしました。(イリア)

バンドルされている PCRE をバージョン 8.12 にアップグレードしました。(スコット)

両方の PCRE バージョンのリリース ノートを読みましたが、UTF8 エンコーディングに言及しているいくつかの修正を除いて、あなたの場合のマッチングに何が影響するかわかりません。

しかし、U修飾子を見ていると、 PCRE 構成オプションで次のことに気付きました。

PCRE のバックトラッキング制限。PHP < 5.3.7 のデフォルトは 100000 です。

私の推測では、U(PCRE_UNGREEDY) 修飾子の一部の修正により、 の間の部分<a>が一致する方法が変更されました。<a>スクレイピングしているページのソースを見ると、以前の PHP バージョンで一致するのは内部 HTML を含まないタグだけなので、これは理にかなっています。

例、これは一致します:

<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>

非常に興味深いが、それを修正する方法は?

<a></a>以前のバージョンの PHP にアクセスできないのでテストできませんが、値が既に含まれているため、タグ内の部分を一致させる必要がないため、正規表現の貪欲な部分を削除することをお勧めします。PDFファイル名:

$pattern = "/<a href=\"([^\"]*.pdf)\">/i";

または

DOM パーサーを使用します。

于 2013-03-25T23:21:40.970 に答える