Frage

Ich möchte eine Seite erstellen, in der alle Bilder, die auf meiner Website residieren mit Titel und alternative Darstellung aufgeführt sind.

Ich schrieb mir schon ein kleines Programm zu finden und alle HTML-Dateien zu laden, aber jetzt bin ich fest, wie src, title und alt von diesem HTML zu extrahieren:

<img src="/image/fluffybunny.jpg" title="Harvey the bunny" alt="a cute little fluffy bunny" />

Ich denke, dies sollte mit etwas Regex getan werden, aber da die Reihenfolge der Tags variieren kann, und ich brauche sie alle, ich weiß wirklich nicht, wie dies auf elegante Weise zu analysieren (ich könnte es tun, um das Fest char von char Art und Weise, aber das ist schmerzhaft).

War es hilfreich?

Lösung

EDIT: jetzt, dass ich besser

kennen

regexp Mit dieser Art von Problem zu lösen, ist HTML-Parser .

Lösung mit regexp

In diesem Fall ist es besser, den Prozess in zwei Teile aufgeteilt:

  • erhalten alle img-Tag
  • extrahieren ihre Metadaten

Ich nehme Ihre doc nicht xHTML streng ist, so können Sie nicht einen XML-Parser verwenden. Z.B. mit dieser Web-Seite Quellcode:

/* 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)" />

[...]
        )

)

Dann erhalten wir alle img-Tag-Attribute mit einer Schleife:

$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 sind CPU-Kapazität, so dass Sie können diese Seite gecached werden sollen. Wenn Sie keine Cache-System haben, können Sie Ihre eigenen zwicken von ob_start und Laden / aus einer Textdatei zu speichern.

Wie funktioniert das Zeug Arbeit?

Zuerst verwenden wir preg_ match_ alle , eine Funktion, die jeden String-Matching, das Muster und ouput es in seiner dritten Parameter.

bekommt

Die regexps:

<img[^>]+>

Wir wenden es auf allen HTML-Web-Seiten. Es kann gelesen werden als jeder Zeichenfolge, die mit "<img" beginnt, enthält nicht ">" Zeichen und endet mit a> .

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

Wir wenden sie nacheinander auf jedem img-Tag. Es kann gelesen werden als jeder String beginnend mit „alt“, „Titel“ oder „src“, dann ein „=“, dann eine „', ein paar Sachen, die nicht‚“‘ und endet mit einem '"'. Isolieren Sie die Unterketten zwischen () .

Schließlich jedes Mal, wenn Sie mit regulären Ausdrücken umgehen wollen, ist es praktisch, gute Werkzeuge zu haben, um sie schnell zu testen. Sehen Sie sich diese Online regexp Tester .

EDIT:. Antwort auf den ersten Kommentar

Es ist wahr, dass ich nicht über die (hoffentlich wenige) Menschen mit einfachen Anführungszeichen denken haben.

Nun, wenn Sie nur verwenden‘, ersetzen Sie einfach alle" durch‘.

Wenn Sie beide mischen. Zuerst sollten Sie selbst :-) schlagen, dann versuchen zu verwenden ( "|") anstelle oder "und [^ ø] ersetzen [^"]

Andere Tipps

$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');
}

Nur ein kleines Beispiel zu geben, von PHP XML-Funktionalität für die Aufgabe mit:

$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'];
}

Ich habe die DOMDocument::loadHTML() Methode verwenden, da diese Methode mit HTML-Syntax umgehen kann und nicht gezwungen, das Eingabedokument XHTML zu sein. Streng genommen, die Umwandlung in eine SimpleXMLElement ist nicht notwendig -. Es macht mit XPath und die XPath-Ergebnisse einfacher

Wenn es XHTML, Ihr Beispiel ist, müssen Sie nur 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);
?>

Ausgabe:

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

Das Skript muss wie folgt geändert werden

foreach( $result[0] as $img_tag)

da preg_match_all Rückkehr Array von Arrays

Sie können verwenden simplehtmldom . Die meisten der jQuery-Selektoren werden in simplehtmldom unterstützt. Ein Beispiel ist unten

gegeben
// 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>'; 

Ich benutzte preg_match es zu tun.

In meinem Fall hatte ich einen String mit genau einen <img>-Tag (und kein anderes Markup), die ich von Wordpress, und ich versuche, das src Attribut zu bekommen, damit ich es durch TimThumb laufen konnte.

// 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);

In dem Muster den Titel oder die Alt zu packen, können Sie einfach $pattern = '/title="([^"]*)"/'; verwenden den Titel oder $pattern = '/title="([^"]*)"/'; greifen die Alt zu greifen. Leider mein regex ist nicht gut genug, alle drei (alt / title / src), obwohl mit einem Durchgang zu greifen.

Hier ist eine PHP-Funktion ich zusammen für einen ähnlichen Zweck von allen oben genannten Informationen hinkte, nämlich Bildtag Breite und Länge Eigenschaften on the fly Einstellung ... ein bisschen klobig, vielleicht, aber scheint zuverlässig zu arbeiten:

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;

}

Hier ist die Lösung, in PHP:

Einfach herunterladen QueryPath, und dann gehen Sie wie folgt:

$doc= qp($myHtmlDoc);

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

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

}

Das ist es, Sie sind fertig!

Ich habe die vielen Kommentare auf dieser Seite lesen, die sich beschweren, dass ein dom Parser ist unnötiger Aufwand. Nun kann es teurer sein als ein bloßer regex Anruf, aber der OP hat erklärt, dass es keine Kontrolle über die Reihenfolge der Attribute in den img-Tags. Diese Tatsache führt zu unnötiger RegexMuster Faltung. Darüber hinaus, ein dom Parser die zusätzlichen Vorteile der Lesbarkeit bietet, Wartbarkeit und dom-Bewusstsein (regex ist nicht dom-aware).

Ich liebe regex und ich antworte viele regex Fragen, aber wenn sie mit gültigen HTML zu tun gibt es selten einen guten Grund, über einen Parser regex.

In der Demonstration unten sehen, wie einfach und sauber DOMDocument Griffe img-Tag-Attribute in beliebiger Reihenfolge mit einer Mischung aus zitiert (und nicht unter Angabe überhaupt). Beachten Sie auch, dass Tags ohne ein gezieltes Attribut nicht störend überhaupt - eine leere Zeichenkette als Wert zur Verfügung gestellt

.

Code: ( Demo )

$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";
}

Ausgabe:

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

Mit dieser Technik in der professionellen Code, den Sie mit einem sauberen Skript verlassen, weniger Schluckauf zu kämpfen, und weniger Kollegen, die Sie gearbeitet woanders wollen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top