2

私は正規表現が苦手です。これが私のシナリオです。

いくつかのテーブルを含む Web ページから情報を抽出しようとしていますが、一意の URL (「very/unique.key」としましょう) が含まれているのは一部のテーブルのみであるため、次のようになります。

<table ....>
   (bunch of content)
</table>

<table ....>
   (bunch of content)
</table>

<table ....>
   (bunch of content + "very/unique.key" keyword)
</table>

<table ....>
   (bunch of content)
</table>

<table ....>
   (bunch of content + "very/unique.key" keyword)
</table>

したがって、「very/unique.key」キーワードを含むすべてのテーブルのコンテンツを抽出する必要があります。そして、これが私が試したパターンです:

$pattern = "#<table[^>]+>((?!\<table)(?=very\/unique\.key).*)<\/table>#i";

これは私に何も返しません....

$pattern = "#<table[^>]+>((?!<table).*)<\/table>#i";

これは、条件があっても、テーブル 1 の開始タグ<table...>から最後のテーブルの終了タグまでのすべてを返します...</table>(?!<table)

これについて私を助けてくれる人に感謝します、ありがとう。

--編集--

これは、DOMを使用してすべてのテーブルをループするために見つけた解決策です

--私の解決策--

    $index;//indexes of all the table(s) that contains the keyword
        $cd = 0;//counter

        $DOM = new DOMDocument();
        $DOM->loadHTMLFile("http://uni.corp/sub/sub/target.php?key=123");
        $xpath = new DomXPath($DOM);
        $tables = $DOM->getElementsByTagName("table");
        for ($n = 0; $n < $tables->length; $n++) {
            $rows = $tables->item($n)->getElementsByTagName("tr");
            for ($i = 0; $i < $rows->length; $i++) {
                $cols = $rows->item($i)->getElementsbyTagName("td");
                for ($j = 0; $j < $cols->length; $j++) {


                     $td = $cols->item($j); // grab the td element
                     $img = $xpath->query('./img',$td)->item(0); // grab the first direct img child element


                    if(isset($img) ){
                        $image = $img->getAttribute('src'); // grab the source of the image
                        echo $image;
                        if($image == "very/unique.key"){
                            echo $cols->item($j)->nodeValue, "\t";
                            $index[$cd] = $n;
                            if($n > $cd){
                                $cd++;
                            }


                            echo $cd . " " . $n;//for troubleshooting
                        }


                    }

                }
                echo "<br/>";
            }
        }   

        //loop that echo out only the table(s) that I want which contains the keyword
        $loop = sizeof($index);
        for ($n = 0; $n < $loop; $n++) {
            $temp = $index[$n];
            $rows = $tables->item($temp)->getElementsbyTagName("tr");
            for ($i = 0; $i < $rows->length; $i++) {
                $cols = $rows->item($i)->getElementsbyTagName("td");                
                for ($j = 0; $j < $cols->length; $j++) {
                    echo $cols->item($j)->nodeValue, "\t";
                    //proccess the extracted table content here
                }
                //echo "<br/>";
            }
        }

しかし、個人的には、正規表現の部分にまだ興味があります。誰かがこの質問の正規表現パターンの解決策を見つけてくれればいいのにと思います。とにかく、これについて私を助けたり助言したりしてくれているすべての人に感謝します(特にAbsoluteƵERØに)。

4

2 に答える 2

2

これは PHP5 で動作します。テーブルを解析preg_match()し、キーをチェックするために使用します。このようなメソッドを使用する理由は、 のようHTMLに構文的に正しく記述する必要がないためXMLです。このため、実際には適切な終了タグがない場合があります。さらに、開始タグと終了タグを REGEX と一致させようとして複数の結果が得られるネストされたテーブルがある場合があります。この方法では、キー自体のみをチェックしており、解析されているドキュメントの形式が適切ではありません。

<?php

$input = "<html>
<table id='1'>
<tr>
<td>This does not contain the key.</td>
</tr>
</table>
<table id='2'>
<tr>
<td>This does contain the unique.key!</td>
</tr>
</table>

<table id='3'>
<tr>
<td>This also contains the unique.key.</td>
</tr>
</table>

</html>";

$html = new DOMDocument;
$html->loadHTML($input);

$findings = array();

$tables = $html->getElementsByTagName('table');
foreach($tables as $table){

    $element = $table->nodeValue;

    if(preg_match('!unique\.key!',$element)){
        $findings[] = $element;
    }
}

print_r($findings);

?>

出力

Array
(
    [0] => This does contain the unique.key!
    [1] => This also contains the unique.key.
)
于 2013-07-26T20:24:14.550 に答える
1

あなたの投稿に対するコメントには同意しますが、解決策を示します。very/unique.key を別のものに置き換えたい場合、正しい正規表現は次のようになります。

#<table(.*)>((.*)very\/unique\.key(.*))<\/table>#imsU

ここで重要なのは、正しい修飾子を使用して、入力文字列で機能するようにすることです。これらの修飾子の詳細については、http: //www.php.net/manual/en/reference.pcre.pattern.modifiers.php を参照してください。

次に、very/unique.key を「foobar」に置き換えた例を示します。

<?php
$string = "
<table ....>
   (bunch of content)
</table>

<table ....>
   (bunch of content)
</table>

<table ....>
   bunch of content very/unique.key 
</table>

<table ....>
   (bunch of content)
</table>

<table ....>
   blabla very/unique.key
</table>
";

$pattern = '#<table(.*)>((.*)very\/unique\.key(.*))<\/table>#imsU';

echo preg_replace($pattern, '<table$1>$3foobar$4</table>', $string);
?>

このコードはまったく同じ文字列を出力しますが、2 つの "very/unique.key" が必要に応じて "foobar" に置き換えられています。

このソリューションは機能する可能性がありますが、最も効率的でも最も簡単な作業でもないことは確かです。Mehdi がコメントで述べたように、PHP には XML (つまり HTML) で動作するように特別に作成された拡張機能があります。

その拡張機能のドキュメントへのリンクは次のとおりです http://www.php.net/manual/en/intro.dom.php

これを使用すると、各テーブル要素を簡単に調べて、一意のキーを持つ要素を見つけることができます。

于 2013-07-26T18:44:47.960 に答える