Bir değiştirmek için düzenli ifade

Ben bir PHP preg_replace görüntüleri () çözümü bulmak bağlantıları arıyor ve ilgili görüntü etiketleri ile değiştirin ediyorum.

Bul:

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

Ile değiştirin:

<img src="http://www.domain.tld/any/valid/path/to/imagefile.ext" alt="imagefile" />

Protokol http:// OLMALIDIR Nerede, "" = değer. Ext geçerli bir görüntü formatı (. Jpg,. Jpeg,. Gif,. Png,. Tif) ZORUNLU ve taban dosya adı alt olur.

I () iş için doğru işlevi preg_replace biliyorum, ama ben regex emmek, bu nedenle herhangi bir yardım büyük beğeni topluyor! TEŞEKKÜRLER!

3 Cevap

Tebrikler, sen nasıl regex HTML ayrıştırmak için yığın taşması sormak için bir milyonuncu müşteri!

[X] [HT] ML düzenli bir dil değil ve güvenilir bir regex çözümlenen olamaz. Bir HTML çözümleyici kullanın. PHP kendisi size DOMDocument verir, ya da tercih edebilir simplehtmldom.

Bu arada, bir dosyanın URL bakarak ne tür söyleyemem. Ve uzantılı bir dosya aslında JPEG olacağını gerçekten, hiçbir garanti 'jpeg.' - Bir JPEG var onun uzantısı olarak '. Jpeg' var hiçbir sebep yoktur. Emin olmak için tek yolu (HEAD isteği kullanarak örneğin) kaynak getirme ve Content-Type başlığına bakmaktır.

Ahh, benim günlük DOM uygulamadır. HTML ve bu html nitelikleri gibi dizeleri ayrıştırmak için regex ayrıştırmak için DOM kullanmak gerekir.

Not: Ben elbette bazı sihirbazlar tarafından üzerine geliştirilmiş olabilir bazı temel Regexes var :)

# Not 2: ekstra yükü olabilir rağmen size href bir HEAD isteği gönderme ve Content-Type bakarak gerçek bir görüntü olup olmadığını iyice kontrol etmek kıvrılma gibi bir şey kullanabilirsiniz, ancak bu vakaların% 80-90 çalışacak .

<?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();

Ben bu daha esnek olmayan greddy regex kullanarak öneririm:

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

Ve (PHP test kodu da dahil olmak üzere) daha karmaşık bir regex umarım bamya lütfen :)

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