Php 正则表达式以替换<;a>;与相应的<;img>;

Php 正则表达式以替换<;a>;与相应的<;img>;,php,regex,preg-replace,Php,Regex,Preg Replace,我正在寻找一个PHP preg_replace()解决方案,找到指向图像的链接并用相应的图像标记替换它们 查找: 替换为: <img src="http://www.domain.tld/any/valid/path/to/imagefile.ext" alt="imagefile" /> 如果协议必须是http://,.ext必须是有效的图像格式(.jpg、.jpeg、.gif、.png、.tif),并且基本文件名成为alt=”“值 我知道preg_replace()是适

我正在寻找一个PHP preg_replace()解决方案,找到指向图像的链接并用相应的图像标记替换它们

查找:


替换为:

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

如果协议必须是http://,.ext必须是有效的图像格式(.jpg、.jpeg、.gif、.png、.tif),并且基本文件名成为alt=”“值


我知道preg_replace()是适合这项工作的函数,但我不喜欢正则表达式,因此非常感谢您的帮助!谢谢

啊,我每天的DOM练习。您应该使用DOM来解析HTML,使用正则表达式来解析字符串,例如HTML属性

注意:我有一些基本正则表达式,一些向导肯定可以改进它们:)

注意#2:虽然这可能会增加额外的开销,但您可以使用类似curl的方法通过发送HEAD请求并查看内容类型来彻底检查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();

祝贺您,您是第一百万个询问Stack Overflow如何使用正则表达式解析HTML的客户

[十] [HT]ML不是一种常规语言,无法用正则表达式可靠地解析。使用HTML解析器。PHP本身给了您,或者您可能更喜欢


顺便说一句,您无法通过查看文件的URL来判断文件的类型。JPEG没有理由必须将“.JPEG”作为其扩展名 — 实际上,不能保证扩展名为“.jpeg”的文件实际上是jpeg。唯一确定的方法是获取资源(例如使用HEAD请求)并查看内容类型标头。

我建议使用更灵活的非灰色正则表达式:

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

乱数假文。。
一些东西:
还有别的。。。
终止

$regex=“/\s]+)?)+>[^-1这并不能解决问题;而且没有人关心用正则表达式解析HTML-如果你是验证图像和创建标记的人,那么你可以相当肯定一切都会很好。确实如此。但是,提问者没有说标记的格式在他们的控制之下。他也没有说不是。你不知道关于上下文,这不应该是一个答案,而是对问题的一个评论。格式化的标记在我的控制之下。这个答案几乎不相关。太长了…这可以用preg_替换完成。看看我的答案。正则表达式解决方案太容易失败,我会坚持使用DOM,但谢谢。另外,DOM解决方案远远不够更灵活的是,您可以执行任何想要的DOM操作,但在正则表达式替换中受到限制。允许属性值包含文本
<a[^>]+?href=\"(http:\/\/[^\"]+?\/([^\"]*?)\.(jpg|jpeg|png|gif))[^>]*?>[^<]*?<\/a>
<?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);
?>