Jak wyodrębnić img src, title i alt z html za pomocą php?
Chciałbym stworzyć stronę, na której wszystkie obrazy znajdujące się na mojej stronie są wymienione z tytułem i alternatywną reprezentacją.
Napisałem już mały program do znajdowania i ładowania wszystkich plików HTML, ale teraz utknąłem w tym, jak wyodrębnić src
, title
i alt
z tego HTML:
<img src="/image/fluffybunny.jpg" title="Harvey the bunny" alt="a cute little fluffy bunny" />
Myślę, że powinno to być zrobione z regex, ale ponieważ kolejność tagów może się różnić, a ja potrzebuję wszystkich z nich, tak naprawdę Nie wiem, jak parsować to w elegancki sposób (mógłbym to zrobić hard char by char way, ale to bolesne).
21 answers
EDIT: now that I know better
Użycie regexp do rozwiązania tego rodzaju problemu jest złym pomysłem i prawdopodobnie doprowadzi do niemożliwego do utrzymania i zawodnego kodu. Lepiej użyć parsera HTML .
Rozwiązanie z wyrażeniem regularnym
W takim przypadku lepiej podzielić proces na dwie części:
- Pobierz wszystkie znaczniki img
- wyodrębnij ich metadane
Zakładam, że Twój doc nie jest ścisły w xHTML, więc nie możesz używać parsera XML. Np. z kod źródłowy tej strony:
/* 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)" />
[...]
)
)
Następnie otrzymujemy wszystkie atrybuty znacznika img z pętlą:
$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"
)
)
[..]
)
)
Wyrażenia regularne są obciążające Procesor, więc możesz chcieć buforować tę stronę. Jeśli nie masz systemu pamięci podręcznej, możesz dostosować swój własny, używając ob_start i ładując / zapisując z pliku tekstowego.
Jak to działa ?Po pierwsze, używamy preg_ match_ all , funkcji, która pobiera każdy łańcuch pasujący do wzorca i usuwa go w trzecim parametr.
Wyrażenia regularne:
<img[^>]+>
Stosujemy go na wszystkich stronach html. Można go odczytać jako każdy łańcuch, który zaczyna się od "<img
", zawiera znak non " > " i kończy się >.
(alt|title|src)=("[^"]*")
Stosujemy go kolejno na każdym tagu img. Można go odczytać jako każdy ciąg znaków zaczynający się od "alt", "title" lub "src", a następnie "=", a następnie"", kilka rzeczy, które nie są ""i kończy się na"". Wyizoluj podciągi pomiędzy () .
Wreszcie, za każdym razem chcesz radzić sobie z wyrażeniami regularnymi, warto mieć dobre narzędzia, aby szybko je przetestować. Sprawdź to Tester regexp online .
EDIT: odpowiedz na pierwszy komentarz.
To prawda, że nie myślałem o (miejmy nadzieję, że niewielu) ludziach używających pojedynczych cytatów.
Cóż, jeśli używasz tylko ', po prostu zamień wszystkie "by".
Jeśli wymieszasz oba. Najpierw powinieneś się uderzyć: -), następnie spróbuj użyć ( " | ') zamiast " i [^ø], aby zastąpić [^"].Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:05
$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');
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-18 02:32:24
Dla małego przykładu użycia funkcji XML PHP dla zadania:
$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'];
}
Użyłem metody DOMDocument::loadHTML()
, ponieważ ta metoda radzi sobie ze składnią HTML i nie wymusza, aby Dokument wejściowy był XHTML. Ściśle mówiąc konwersja do SimpleXMLElement
nie jest konieczna - po prostu sprawia, że korzystanie z xpath i wyniki XPath są prostsze.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-26 10:40:36
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:03:05
Jeśli jest to XHTML, twój przykład jest taki, że potrzebujesz tylko 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);
?>
Wyjście:
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"
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-26 10:30:44
Skrypt musi być edytowany w ten sposób
foreach( $result[0] as $img_tag)
Ponieważ preg_match_all zwraca tablicę tablic
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-18 02:32:50
RE To rozwiązanie:
$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');
}
Jak uzyskać tag i atrybut z wielu plików / adresów URL?
Robienie tego nie zadziałało na mnie: foreach (glob("path/to/files/*.html") as $html) {
$doc = new DOMDocument();
$doc->loadHTML($html);
$tags = $doc->getElementsByTagName('img');
foreach ($tags as $tag) {
echo $tag->getAttribute('src');
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-17 07:02:18
Możesz użyć simplehtmldom . Większość selektorów jQuery jest obsługiwana w simplehtmldom. Przykład podano poniżej
// 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>';
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-27 07:24:20
Oto funkcja PHP, którą połączyłem ze wszystkimi powyższymi informacjami w podobnym celu, a mianowicie dostosowywanie właściwości znaczników szerokości i długości obrazu w locie ... może trochę niezgrabne, ale wydaje się działać niezawodnie:
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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-09 07:57:35
Użyłem do tego preg_match.
W moim przypadku miałem ciąg zawierający dokładnie jeden <img>
tag (i żadnych innych znaczników), który dostałem z WordPressa i próbowałem uzyskać atrybut src
, aby móc go uruchomić przez 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);
W szablonie, aby pobrać tytuł lub alt, możesz po prostu użyć $pattern = '/title="([^"]*)"/';
, Aby pobrać tytuł lub $pattern = '/title="([^"]*)"/';
, Aby pobrać alt. Niestety, mój regex nie jest wystarczająco dobry, aby pobrać wszystkie trzy (alt / title / src)z jednym przejściem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-28 16:59:34
Możesz również wypróbować SimpleXML, jeśli HTML jest gwarantowany jako XHTML - przetworzy znaczniki dla Ciebie i będziesz mógł uzyskać dostęp do atrybutów po ich nazwie. (Istnieją również biblioteki DOM, jeśli jest to tylko HTML i nie można polegać na składni XML.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-26 08:35:35
Możesz napisać Wyrażenie regularne, aby pobrać wszystkie znaczniki img (<img[^>]*>
), a następnie użyć simple explode: $res = explode("\"", $tags)
, wynik będzie taki:
$res[0] = "<img src=";
$res[1] = "/image/fluffybunny.jpg";
$res[2] = "title=";
$res[3] = "Harvey the bunny";
$res[4] = "alt=";
$res[5] = "a cute little fluffy bunny";
$res[6] = "/>";
Jeśli usuniesz znacznik <img
przed wybuchem, otrzymasz tablicę w postaci
property=
value
Więc kolejność właściwości nie ma znaczenia, używasz tylko tego, co chcesz.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-26 08:49:26
Oto rozwiązanie, w PHP:
Po prostu pobierz QueryPath, a następnie wykonaj następujące czynności:
$doc= qp($myHtmlDoc);
foreach($doc->xpath('//img') as $img) {
$src= $img->attr('src');
$title= $img->attr('title');
$alt= $img->attr('alt');
}
Koniec z Tobą !Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-11-13 13:52:25
Poniższy kod zadziałał u mnie w WordPressie...
Wydobywa wszystkie źródła obrazu z kodu
$search = "any html code with image tags";
preg_match_all( '/src="([^"]*)"/', $search, $matches);
if ( isset( $matches ) )
{
foreach ($matches as $match)
{
if(strpos($match[0], "src")!==false)
{
$res = explode("\"", $match[0]);
$image = parse_url($res[1], PHP_URL_PATH);
$xml .= " <image:image>\n";
$xml .= " <image:loc>".home_url().$image."</image:loc>\n";
$xml .= " <image:caption>".htmlentities($title)."</image:caption>\n";
$xml .= " <image:license>".home_url()."</image:license>\n";
$xml .= " </image:image>\n";
}
}
}
Zdrówko!Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-24 08:38:24
$content = "<img src='http://google.com/2af5e6ae749d523216f296193ab0b146.jpg' width='40' height='40'>";
$image = preg_match_all('~<img rel="imgbot" remote="(.*?)" width="(.*?)" height="(.*?)" linktext="(.*?)" linkhref="(.*?)" src="(.*?)" />~is', $content, $matches);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-05 15:26:41
Jeśli chcesz użyć regEx dlaczego nie tak proste jak to:
preg_match_all('% (.*)=\"(.*)\"%Uis', $code, $matches, PREG_SET_ORDER);
To zwróci coś w stylu:
array(2) {
[0]=>
array(3) {
[0]=>
string(10) " src="abc""
[1]=>
string(3) "src"
[2]=>
string(3) "abc"
}
[1]=>
array(3) {
[0]=>
string(10) " bla="123""
[1]=>
string(3) "bla"
[2]=>
string(3) "123"
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-17 20:08:41
Istnieje moje rozwiązanie do pobierania tylko obrazów z treści dowolnego postu w WordPress lub treści html. `
$content = get_the_content();
$count = substr_count($content, '<img');
$start = 0;
for ($i=0;$i<$count;$i++) {
if ($i == 0){
$imgBeg = strpos($content, '<img', $start);
$post = substr($content, $imgBeg);
} else {
$imgBeg = strpos($post, '<img', $start);
$post = substr($post, $imgBeg-2);
}
$imgEnd = strpos($post, '>');
$postOutput = substr($post, 0, $imgEnd+1);
$postOutput = preg_replace('/width="([0-9]*)" height="([0-9]*)"/', '',$postOutput);
$image[$i] = $postOutput;
$start= $imgEnd + 1;
}
print_r($image);
`
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-09 07:56:48
"]+>]+>/)?>"
spowoduje to wyodrębnienie znacznika zakotwiczenia zagnieżdżonego z znacznikiem obrazu
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-29 06:31:55
Dla jednego elementu można użyć tego zminifikowanego rozwiązania używając DOMDocument. Obsługuje zarówno cudzysłowy 'jak i", a także waliduje html. Najlepszą praktyką jest używanie istniejących bibliotek zamiast własnych rozwiązań przy użyciu wyrażeń regularnych.
$html = '<img src="/image/fluffybunny.jpg" title="Harvey the bunny" alt="a cute little fluffy bunny" />';
$attribute = 'src';
$doc = new DOMDocument();
@$doc->loadHTML($html);
$attributeValue = @$doc->documentElement->firstChild->firstChild->attributes->getNamedItem($attribute)->value;
echo $attributeValue;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-31 10:30:38
Może użyjesz wyrażenia regularnego, aby znaleźć znaczniki img (coś w rodzaju "<img[^>]*>"
), a następnie, dla każdego znacznika img, możesz użyć innego wyrażenia regularnego, aby znaleźć każdy atrybut.
Może coś w stylu " ([a-zA-Z]+)=\"([^"]*)\""
, aby znaleźć atrybuty, chociaż możesz chcieć zezwolić na cudzysłowy, których nie ma, Jeśli masz do czynienia z zupą tagów... Jeśli to zrobisz, możesz uzyskać nazwę parametru i wartość z grup w każdym meczu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-26 08:47:22
Może to da ci właściwe odpowiedzi:
<img.*?(?:(?:\s+(src)="([^"]+)")|(?:\s+(alt)="([^"]+)")|(?:\s+(title)="([^"]+)")|(?:\s+[^\s]+))+.*/>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-09 13:05:33