0
4

3 に答える 3

10

おめでとうございます。あなたは Stack Overflow に HTML を正規表現で解析する方法を尋ねた 100 万人目の顧客です。

[X][HT]ML は通常の言語ではないため、正規表現で確実に解析することはできません。HTML パーサーを使用します。PHP 自体がDOMDocumentを提供するか、 simplehtmldomを好むかもしれません。

ちなみに、URL を見ただけでは、ファイルの種類を判断することはできません。JPEG の拡張子が「.jpeg」でなければならない理由はありません。実際、拡張子が「.jpeg」のファイルが実際に JPEG であるという保証もありません。確認する唯一の方法は、リソースをフェッチし (例: HEAD リクエストを使用)、Content-Type ヘッダーを確認することです。

于 2009-09-19T23:23:35.937 に答える
7

ああ、私の毎日のDOMの練習。HTML を解析するには DOM を使用し、html 属性などの文字列を解析するには regex を使用する必要があります。

注:いくつかのウィザードによって確実に改善される可能性のある基本的な正規表現がいくつかあります:)

注 #2: 追加のオーバーヘッドが発生する可能性がありますが、curl などを使用して、HEAD リクエストを送信し、Content-Type を確認することで、href が実際の画像かどうかを徹底的に確認できますが、これは 80 ~ 90% のケースで機能します。 .

<?php

$content = '

<a href="http://www.domain.tld/any/valid/path/to/imagefile.ext">This will be ignored.</a>
<br>

<a href="http://col.stb.s-msn.com/i/43/A4711309495C88F8CD154C99FCE.jpg">this will not be ignored</a>

<br>

<a href="http://col.stb.s-msn.com/i/A0/8E9A454F701E4F5F89E58E14B532C.jpg">bah</a>
';

$dom = new DOMDocument();
$dom->loadHTML($content);

$anchors = $dom->getElementsByTagName('a');

$i = $anchors->length-1;

$protocol = '/^http:\/\//';
$ext = '/([\w+]+)\.(?:gif|jpg|jpeg|png)$/';

if ( count($anchors->length) > 0 ) {
    while( $i > -1 ) {
    $anchor = $anchors->item($i);
    if ( $anchor->hasAttribute('href') ) {
        $link = $anchor->getAttribute('href');

        if ( 
        preg_match ( $protocol , $link ) &&
        preg_match ( $ext, $link )
        ) {
        //echo 'replacing this one.';
        $image = $dom->createElement('img');

        if ( preg_match( $ext, $link, $matches ) ) {
            if ( count($matches) ) {
            $altName = $matches[1];
            $image->setAttribute('alt', $altName);
            }
            $image->setAttribute('src', $link);
            $anchor->parentNode->replaceChild( $image, $anchor );
        }
        }

    }
    $i--;
    }
}

echo $dom->saveHTML();
于 2009-09-19T23:22:27.313 に答える
1

このより柔軟な非 greddy 正規表現を使用することをお勧めします。

<a[^>]+?href=\"(http:\/\/[^\"]+?\/([^\"]*?)\.(jpg|jpeg|png|gif))[^>]*?>[^<]*?<\/a>

そして、うまくいけばGumboを喜ばせるためのより複雑な正規表現(PHPテストコードを含む):)

<?php
$test_data = <<<END
<a blabla="asldlsaj" alksjada="aslkdj" href="http://www.domain.tld/any/valid/path/to/imagefile.jpg" lkjasd=""asdlaskjd>This will be ignored.</a>
Lorem ipsum..
<a    blabla=asldlsaj alksjada="aslkdj" href="http://www.domain.tld/any/valid/path/to/imagefile.jpg" lkjasd=""asdlaskjd>This will be ignored.</a>
<a lkjafs='asdsa> ' blabla="asldlksjada=>"aslkdj" href="http://www.domain.tld/any/valid/path/to/imagefile.jpg" lkjasd=""asdlaskjd>This will be ignored.</a>
<a    blabla="ajada="aslk href="http://www.domain.tld/any/valid/path>/to/imagefile.jpg" lkjasd>asdlaskjd>This will be ignored.</a>
<a    blabla="asldlsaj>" aslkdj href="http://www.domain.tld/any/valid/path/ to/imagefile.jpg" lkjasd=""asdlaskjd>This will be ignored.</a>
Something:
<a    blabla='asldls<ajslkdj' href="http://www.domain.tld/any/valid'/path/to/imagefile.jpg" lkjasd=""asdlaskjd>This will be ignored.</a>
<a    blabla=  asldlsadj href="http://www.domain.tld/any/valid/path/to/imagefile.jpg" lkjasd>This will be ignored.</a>
<a blabla="asldlsaj" alksjslkdj" href='http://www.domain.tld/any/valid/path/to/imagefile.jpg' lkjasdskjd>This will be ignored.</a>
Something else...
<a    blabla="asldlsaj" alksjslkdj" href='http://www.domain.tld/any/valid/path/to/imagefile.jpg' lkjasdskjd>This will be ignored.</a>
<a    blabla="asldlsaj" alksjada="aslkdj" href=http://www.domain.tld/any/valid/path/to/imagefile.jpg lkjdlaskjdll> be ignored.</a>
END;
$regex = "/<a\s(\s*\w+(\s*=\s*(\".*?\"|'.*?'|[^'\">\s]+))?)+?\s+href\s*=\s*(\"(http:\/\/[^\"]+\/(.*?)\.(jpg|jpeg|png|gif))\"|'(http:\/\/[^']+\/(.*?)\.(jpg|jpeg|png|gif))'|(http:\/\/[^'\">\s]+\/([^'\">\s]+)\.(jpg|jpeg|png|gif)))\s(\s*\w+(\s*=\s*(\".*?\"|'.*?'|[^'\">\s]+))?)+>[^<]*?<\/a>/i";
$replaced = preg_replace($regex, '<img src="$5$8$11" alt="$6$9$12" />', $test_data);

echo '<pre>'.htmlentities($replaced);
?>
于 2009-11-15T15:12:42.707 に答える