0

次の入力文字列、パターン、および :

$str1 = 'span class="outline">Iron Man butts heads with Nick Fury and Shield after HYDRA attacks a meeting of the United Nations.</span>
<span class="credit">
    Dir: <a href="/name/nm0381817/">Vinton Heuck</a>, <a href="/name/nm1367649/">Ciro Nieli</a>, <a href="/name/nm1367649/">Aditya Parikh</a>'

$pattern='/class=&quot;credit&quot;&gt;[\s]+?Dir:([,\s]+?&lt;a[\s]+?href=&quot;\/name\/nm\d{7}\/&quot;&gt;([\/\(\)-:@!%*#=_|?$&;.\w\s]+?)&lt;\/a&gt;)+/um';

preg_match_all($pattern,$str1,$dir);

print_r の出力は次のとおりです。

Array ( [0] => Array ( [0] => class="credit"> Dir: <a href="/name/nm0381817/">Vinton Heuck</a>, <a href="/name/nm1367649/">Ciro Nieli</a>, <a href="/name/nm1367649/">Aditya Parikh</a> ) [1] => Array ( [0] => , <a href="/name/nm1367649/">Aditya Parikh</a> ) [2] => Array ( [0] => Aditya Parikh ) )

Array[2] が Aditya Parikh を与えることがわかるように、Vinton Heuck と Ciro Nieli も受け取ることを望んでいました。しかし、しませんでした。

解決策はありますか??

4

2 に答える 2

1

によって返される一致する配列の背後にあるロジックpreg_match_allは、それほど明白ではありません。

まず、正規表現を使用して html を解析しないでください。とは言うものの:

得られる結果は、 の形式になり$array[paren_num][match_num]ます。

基本的な例: abc正規表現に対して実行すると/(.)/、次の一致する配列が返されます。

Array
(
    [0] => Array
        (
            [0] => a
            [1] => b
            [2] => c
        )

    [1] => Array
        (
            [0] => a
            [1] => b
            [2] => c
        )

)

インデックス 0 には、消費されたすべてのデータが含まれます。インデックス 1 は、最初の後方参照であることを意味します (かっこは 1 つしかありません)。その中の 0 ~ 2 のインデックスは、各試合に対応します。つまり、式は完了するまで 3 回実行されました。

これが役立つことを願っています。

于 2012-10-22T08:43:40.537 に答える
1

DOM パーサーの使用を検討する必要があります。たとえば、これ正規表現は HTML を適切に解析できません。

ただし、アプローチが期待どおりに機能しない理由は次のとおりです。

3 つの名前すべてに同じキャプチャ グループを使用しています。ただし、キャプチャ グループには番号が 1 つしかないため、最後にキャプチャされたもの (一番右の名前) だけが取得されます。spanしかし、1 つの名前 (任意にタグの奥まで) を一致させただけでも、別の問題が発生します。

試合は重複できません。必要な 3 つの一致すべてに、少なくともclass="credit"> Dir:いくつかのより一般的なテキストが含まれているため、それらすべてを取得することはできません。これは後読みアサーションで解決できますが (これは一致の一部ではないため)、残念ながら PHP では可変長後読みが許可されていません (これは必須です)。これを解決するための回避策がありますが、結局のところ、DOM パーサーを使用するのが最善です。

上記でリンクしたパーサーを使用した基本的な例を次に示します。

require "simple_html_dom.php";

$html = str_get_html($str1);

$names = array();
foreach($html->find('span[class=credit] a') as $link)
    $names[] = $link->innertext;

print_r($names);

その結果:

Array
(
    [0] => Vinton Heuck
    [1] => Ciro Nieli
    [2] => Aditya Parikh
)
于 2012-10-22T08:59:03.327 に答える