문제

내 웹 사이트에있는 모든 이미지에 제목과 대체 표현이 표시되는 페이지를 만들고 싶습니다.

나는 이미 모든 HTML 파일을 찾고로드하기위한 작은 프로그램을 이미 작성했지만 이제는 추출하는 방법에 갇혀 있습니다. src, title 그리고 alt 이 HTML에서 :

<img SRC="/image/fluffybunny.jpg" 제목="Harvey the bunny" 대체="a cute little fluffy bunny" />

나는 이것이 약간의 정규식으로 이루어져야한다고 생각하지만, 태그의 순서가 다를 수 있고, 그들 모두가 필요하기 때문에, 나는 이것을 우아한 방식으로 구문 분석하는 방법을 실제로 모른다 (나는 하드 숯으로 할 수있다. char way, 그러나 그것은 고통 스럽습니다).

도움이 되었습니까?

해결책

편집 : 이제 더 잘 알았습니다

이런 종류의 문제를 해결하기 위해 regexp를 사용하는 것은입니다 나쁜 생각 그리고 인재 할 수없고 신뢰할 수없는 코드로 이어질 것입니다. 더 잘 사용합니다 HTML 파서.

Regexp를 사용한 솔루션

이 경우 프로세스를 두 부분으로 나누는 것이 좋습니다.

  • 모든 IMG 태그를 얻으십시오
  • 메타 데이터를 추출하십시오

나는 당신의 문서가 XHTML이 엄격하지 않다고 가정하므로 XML 파서를 사용할 수 없습니다. 예 :이 웹 페이지 소스 코드와 함께 :

/* preg_match_all match the regexp in all the $html string and output everything as 
an array in $result. "i" option is used to make it case insensitive */

preg_match_all('/<img[^>]+>/i',$html, $result); 

print_r($result);
Array
(
    [0] => Array
        (
            [0] => <img src="/Content/Img/stackoverflow-logo-250.png" width="250" height="70" alt="logo link to homepage" />
            [1] => <img class="vote-up" src="/content/img/vote-arrow-up.png" alt="vote up" title="This was helpful (click again to undo)" />
            [2] => <img class="vote-down" src="/content/img/vote-arrow-down.png" alt="vote down" title="This was not helpful (click again to undo)" />
            [3] => <img src="http://www.gravatar.com/avatar/df299babc56f0a79678e567e87a09c31?s=32&d=identicon&r=PG" height=32 width=32 alt="gravatar image" />
            [4] => <img class="vote-up" src="/content/img/vote-arrow-up.png" alt="vote up" title="This was helpful (click again to undo)" />

[...]
        )

)

그런 다음 모든 IMG 태그 속성을 루프로 얻습니다.

$img = array();
foreach( $result as $img_tag)
{
    preg_match_all('/(alt|title|src)=("[^"]*")/i',$img_tag, $img[$img_tag]);
}

print_r($img);

Array
(
    [<img src="/Content/Img/stackoverflow-logo-250.png" width="250" height="70" alt="logo link to homepage" />] => Array
        (
            [0] => Array
                (
                    [0] => src="/Content/Img/stackoverflow-logo-250.png"
                    [1] => alt="logo link to homepage"
                )

            [1] => Array
                (
                    [0] => src
                    [1] => alt
                )

            [2] => Array
                (
                    [0] => "/Content/Img/stackoverflow-logo-250.png"
                    [1] => "logo link to homepage"
                )

        )

    [<img class="vote-up" src="/content/img/vote-arrow-up.png" alt="vote up" title="This was helpful (click again to undo)" />] => Array
        (
            [0] => Array
                (
                    [0] => src="/content/img/vote-arrow-up.png"
                    [1] => alt="vote up"
                    [2] => title="This was helpful (click again to undo)"
                )

            [1] => Array
                (
                    [0] => src
                    [1] => alt
                    [2] => title
                )

            [2] => Array
                (
                    [0] => "/content/img/vote-arrow-up.png"
                    [1] => "vote up"
                    [2] => "This was helpful (click again to undo)"
                )

        )

    [<img class="vote-down" src="/content/img/vote-arrow-down.png" alt="vote down" title="This was not helpful (click again to undo)" />] => Array
        (
            [0] => Array
                (
                    [0] => src="/content/img/vote-arrow-down.png"
                    [1] => alt="vote down"
                    [2] => title="This was not helpful (click again to undo)"
                )

            [1] => Array
                (
                    [0] => src
                    [1] => alt
                    [2] => title
                )

            [2] => Array
                (
                    [0] => "/content/img/vote-arrow-down.png"
                    [1] => "vote down"
                    [2] => "This was not helpful (click again to undo)"
                )

        )

    [<img src="http://www.gravatar.com/avatar/df299babc56f0a79678e567e87a09c31?s=32&d=identicon&r=PG" height=32 width=32 alt="gravatar image" />] => Array
        (
            [0] => Array
                (
                    [0] => src="http://www.gravatar.com/avatar/df299babc56f0a79678e567e87a09c31?s=32&d=identicon&r=PG"
                    [1] => alt="gravatar image"
                )

            [1] => Array
                (
                    [0] => src
                    [1] => alt
                )

            [2] => Array
                (
                    [0] => "http://www.gravatar.com/avatar/df299babc56f0a79678e567e87a09c31?s=32&d=identicon&r=PG"
                    [1] => "gravatar image"
                )

        )

   [..]
        )

)

Regexps는 CPU 집중적 이므로이 페이지를 캐시 할 수 있습니다. 캐시 시스템이없는 경우 사용하여 직접 조정할 수 있습니다. OB_START 및 텍스트 파일에서로드 / 저장.

이 물건은 어떻게 작동합니까?

먼저, 우리는 사용합니다 preg_ match_ 모두, 모든 문자열이 패턴과 일치하고 세 번째 매개 변수에 넣는 함수.

regexps :

<img[^>]+>

모든 HTML 웹 페이지에 적용합니다. 읽을 수 있습니다 "로 시작하는 모든 문자열" "<img", 비"> "char를 포함하고>로 끝납니다..

(alt|title|src)=("[^"]*")

각 IMG 태그에 연속적으로 적용합니다. 읽을 수 있습니다 "alt", "title"또는 "src", 그런 다음 "=", a ' ",' '', '' ''로 끝나는 모든 문자열은 '' ''로 끝납니다. () 사이의 문자열.

마지막으로, regexps를 다룰 때마다 빠르게 테스트 할 수있는 좋은 도구를 갖는 것이 편리합니다. 이것을 확인하십시오 온라인 Regexp 테스터.

편집 : 첫 번째 주석에 대한 답변.

단일 인용문을 사용하는 사람들에 대해 생각하지 않았다는 것은 사실입니다.

글쎄, 만 사용하는 경우 '만 사용하면'by '를 교체하십시오.

둘 다 섞으면. 먼저 자신을 때려야합니다 :-), 그런 다음 [^"]를 대체하기 위해 ("| ') 대신 ( "|')와 [^Ø]를 사용하려고 노력하십시오.

다른 팁

$url="http://example.com";

$html = file_get_contents($url);

$doc = new DOMDocument();
@$doc->loadHTML($html);

$tags = $doc->getElementsByTagName('img');

foreach ($tags as $tag) {
       echo $tag->getAttribute('src');
}

작업에 PHP의 XML 기능을 사용하는 작은 예를 제공하기 위해서는 다음과 같습니다.

$doc=new DOMDocument();
$doc->loadHTML("<html><body>Test<br><img src=\"myimage.jpg\" title=\"title\" alt=\"alt\"></body></html>");
$xml=simplexml_import_dom($doc); // just to make xpath more simple
$images=$xml->xpath('//img');
foreach ($images as $img) {
    echo $img['src'] . ' ' . $img['alt'] . ' ' . $img['title'];
}

나는 그것을 사용했다 DOMDocument::loadHTML() 이 메소드는 HTML-Syntax에 대처할 수 있고 입력 문서가 XHTML이되지 않기 때문에 방법. 엄밀히 말하면 a 로의 전환 SimpleXMLElement 필요하지 않습니다. XPath를 사용하고 XPath 결과를 더 간단하게 만듭니다.

XHTML 인 경우 예제는 SimpleXML 만 필요합니다.

<?php
$input = '<img src="/image/fluffybunny.jpg" title="Harvey the bunny" alt="a cute little fluffy bunny"/>';
$sx = simplexml_load_string($input);
var_dump($sx);
?>

산출:

object(SimpleXMLElement)#1 (1) {
  ["@attributes"]=>
  array(3) {
    ["src"]=>
    string(22) "/image/fluffybunny.jpg"
    ["title"]=>
    string(16) "Harvey the bunny"
    ["alt"]=>
    string(26) "a cute little fluffy bunny"
  }
}

스크립트는 다음과 같이 편집해야합니다

foreach( $result[0] as $img_tag)

preg_match_all 배열의 배열이기 때문에

당신은 사용할 수 있습니다 simplehtmldom. 대부분의 jQuery 선택기는 SimpleHtmlom에서 지원됩니다. 예는 다음과 같습니다

// Create DOM from URL or file
$html = file_get_html('http://www.google.com/');

// Find all images
foreach($html->find('img') as $element)
       echo $element->src . '<br>';

// Find all links
foreach($html->find('a') as $element)
       echo $element->href . '<br>'; 

나는 preg_match를 사용하여 그것을 사용했습니다.

제 경우에는 정확히 하나를 포함하는 문자열이있었습니다. <img> WordPress에서 얻은 태그 (및 다른 마크 업은) src Timthumb를 통해 실행할 수 있도록 속성.

// get the featured image
$image = get_the_post_thumbnail($photos[$i]->ID);

// get the src for that image
$pattern = '/src="([^"]*)"/';
preg_match($pattern, $image, $matches);
$src = $matches[1];
unset($matches);

제목이나 alt를 가져 오려는 패턴에서 단순히 사용할 수 있습니다. $pattern = '/title="([^"]*)"/'; 제목을 잡으려면 또는 $pattern = '/title="([^"]*)"/'; Alt를 잡으려면. 안타깝게도 내 동정형은 하나의 패스로 세 가지 (Alt/Title/SRC)를 모두 잡기에 충분하지 않습니다.

다음은 비슷한 목적을 위해 위의 모든 정보에서 함께 모은 PHP 기능입니다. 즉, 이미지 태그 너비와 길이 속성을 즉시 조정하는 것입니다.

function ReSizeImagesInHTML($HTMLContent,$MaximumWidth,$MaximumHeight) {

// find image tags
preg_match_all('/<img[^>]+>/i',$HTMLContent, $rawimagearray,PREG_SET_ORDER); 

// put image tags in a simpler array
$imagearray = array();
for ($i = 0; $i < count($rawimagearray); $i++) {
    array_push($imagearray, $rawimagearray[$i][0]);
}

// put image attributes in another array
$imageinfo = array();
foreach($imagearray as $img_tag) {

    preg_match_all('/(src|width|height)=("[^"]*")/i',$img_tag, $imageinfo[$img_tag]);
}

// combine everything into one array
$AllImageInfo = array();
foreach($imagearray as $img_tag) {

    $ImageSource = str_replace('"', '', $imageinfo[$img_tag][2][0]);
    $OrignialWidth = str_replace('"', '', $imageinfo[$img_tag][2][1]);
    $OrignialHeight = str_replace('"', '', $imageinfo[$img_tag][2][2]);

    $NewWidth = $OrignialWidth; 
    $NewHeight = $OrignialHeight;
    $AdjustDimensions = "F";

    if($OrignialWidth > $MaximumWidth) { 
        $diff = $OrignialWidth-$MaximumHeight; 
        $percnt_reduced = (($diff/$OrignialWidth)*100); 
        $NewHeight = floor($OrignialHeight-(($percnt_reduced*$OrignialHeight)/100)); 
        $NewWidth = floor($OrignialWidth-$diff); 
        $AdjustDimensions = "T";
    }

    if($OrignialHeight > $MaximumHeight) { 
        $diff = $OrignialHeight-$MaximumWidth; 
        $percnt_reduced = (($diff/$OrignialHeight)*100); 
        $NewWidth = floor($OrignialWidth-(($percnt_reduced*$OrignialWidth)/100)); 
        $NewHeight= floor($OrignialHeight-$diff); 
        $AdjustDimensions = "T";
    } 

    $thisImageInfo = array('OriginalImageTag' => $img_tag , 'ImageSource' => $ImageSource , 'OrignialWidth' => $OrignialWidth , 'OrignialHeight' => $OrignialHeight , 'NewWidth' => $NewWidth , 'NewHeight' => $NewHeight, 'AdjustDimensions' => $AdjustDimensions);
    array_push($AllImageInfo, $thisImageInfo);
}

// build array of before and after tags
$ImageBeforeAndAfter = array();
for ($i = 0; $i < count($AllImageInfo); $i++) {

    if($AllImageInfo[$i]['AdjustDimensions'] == "T") {
        $NewImageTag = str_ireplace('width="' . $AllImageInfo[$i]['OrignialWidth'] . '"', 'width="' . $AllImageInfo[$i]['NewWidth'] . '"', $AllImageInfo[$i]['OriginalImageTag']);
        $NewImageTag = str_ireplace('height="' . $AllImageInfo[$i]['OrignialHeight'] . '"', 'height="' . $AllImageInfo[$i]['NewHeight'] . '"', $NewImageTag);

        $thisImageBeforeAndAfter = array('OriginalImageTag' => $AllImageInfo[$i]['OriginalImageTag'] , 'NewImageTag' => $NewImageTag);
        array_push($ImageBeforeAndAfter, $thisImageBeforeAndAfter);
    }
}

// execute search and replace
for ($i = 0; $i < count($ImageBeforeAndAfter); $i++) {
    $HTMLContent = str_ireplace($ImageBeforeAndAfter[$i]['OriginalImageTag'],$ImageBeforeAndAfter[$i]['NewImageTag'], $HTMLContent);
}

return $HTMLContent;

}

PHP의 해결책은 다음과 같습니다.

QueryPath를 다운로드 한 다음 다음과 같이 수행하십시오.

$doc= qp($myHtmlDoc);

foreach($doc->xpath('//img') as $img) {

   $src= $img->attr('src');
   $title= $img->attr('title');
   $alt= $img->attr('alt');

}

그게 다야, 끝났어!

이 페이지에서 DOM 파서를 사용하는 것이 불필요한 오버 헤드라고 불평하는 많은 의견을 읽었습니다. 글쎄, 그것은 단순한 Regex 호출보다 더 비쌀 수 있지만 OP는 IMG 태그의 속성 순서에 대한 통제가 없다고 진술했습니다. 이 사실은 불필요한 정규 패턴 컨볼 루션으로 이어집니다. 그 외에도 Dom Parser를 사용하면 가독성, 유지 관리 및 DOM 인식의 추가 이점이 제공됩니다 (Regex는 Dom-Aware가 아닙니다).

나는 Regex를 좋아하고 많은 Regex 질문에 대답하지만, 유효한 HTML을 다룰 때는 파서에 대한 재배치가 거의 없습니다.

아래 데모에서 인용이 혼합 된 (그리고 전혀 인용하지 않음) 순서로 IMG 태그 속성을 쉽게 처리하는 방법을 참조하십시오. 또한 타겟팅 된 속성이없는 태그는 전혀 파괴적이지 않습니다. 빈 문자열은 값으로 제공됩니다.

코드 : (데모)

$test = <<<HTML
<img src="/image/fluffybunny.jpg" title="Harvey the bunny" alt="a cute little fluffy bunny" />
<img src='/image/pricklycactus.jpg' title='Roger the cactus' alt='a big green prickly cactus' />
<p>This is irrelevant text.</p>
<img alt="an annoying white cockatoo" title="Polly the cockatoo" src="/image/noisycockatoo.jpg">
<img title=something src=somethingelse>
HTML;

libxml_use_internal_errors(true);  // silences/forgives complaints from the parser (remove to see what is generated)
$dom = new DOMDocument();
$dom->loadHTML($test);
foreach ($dom->getElementsByTagName('img') as $i => $img) {
    echo "IMG#{$i}:\n";
    echo "\tsrc = " , $img->getAttribute('src') , "\n";
    echo "\ttitle = " , $img->getAttribute('title') , "\n";
    echo "\talt = " , $img->getAttribute('alt') , "\n";
    echo "---\n";
}

산출:

IMG#0:
    src = /image/fluffybunny.jpg
    title = Harvey the bunny
    alt = a cute little fluffy bunny
---
IMG#1:
    src = /image/pricklycactus.jpg
    title = Roger the cactus
    alt = a big green prickly cactus
---
IMG#2:
    src = /image/noisycockatoo.jpg
    title = Polly the cockatoo
    alt = an annoying white cockatoo
---
IMG#3:
    src = somethingelse
    title = something
    alt = 
---

이 기술을 전문 코드로 사용하면 깨끗한 대본, 딸꾹질이 적고 다른 곳에서 일하기를 원하는 동료가 적습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top