PHP中用于替换HTML src属性的正则表达式

10
我想用正则表达式在PHP中替换源属性(可以是图像或任何标记)。
我有一个像这样的字符串:
$string2 = "<html><body><img src = 'images/test.jpg' /><img src = 'http://test.com/images/test3.jpg'/><video controls="controls" src='../videos/movie.ogg'></video></body></html>";

我想把它变成:

$string2 = "<html><body><img src = 'test.jpg' /><img src = 'test3.jpg'/><video controls="controls" src='movie.ogg'></video></body></html>";

这是我尝试过的内容:

$string2 = preg_replace("/src=["']([/])(.*)?["'] /", "'src=' . convert_url('$1') . ')'" , $string2);
echo htmlentities ($string2);

基本上它没有改变任何东西,并给了我有关未转义字符串的警告。

$1 不是把字符串内容发送吗?这里出了什么问题吗?

而 convert_url 函数是我之前发布的一个示例:

function convert_url($url)
{
    if (preg_match('#^https?://#', $url)) {
        $url = parse_url($url, PHP_URL_PATH);
    }
    return basename($url);
}

它应该剥离掉URL路径,只返回文件名。


原始字符串和您要转换的字符串都是空字符串——是否有什么遗漏? - ametren
1
你真的不应该使用正则表达式解析HTML。如果你在SO上搜索,你会找到一个相当全面的答案。同时,我可以建议使用DOM或SimpleXML。 - GordonM
我是说尝试在正则表达式中将所有的 " 替换为 ",但不包括第一个和最后一个。 - Alexandre Khoury
可能是获取A元素的href属性的重复问题。 - Gordon
另外,如果您想使用正则表达式并在替换中使用函数,则需要使用 preg_replace_callback。您不能像平常那样使用 convert_url('$1'),因为这会在 $1 存在之前进行评估。 - Gordon
3个回答

15

不要在HTML上使用正则表达式-请使用DOMDocument类。

$html = "<html>
           <body>
             <img src='images/test.jpg' />
             <img src='http://test.com/images/test3.jpg'/>
             <video controls='controls' src='../videos/movie.ogg'></video>
           </body>
         </html>";

$dom = new DOMDocument;  
libxml_use_internal_errors(true);

$dom->loadHTML( $html ); 
$xpath = new DOMXPath( $dom );
libxml_clear_errors();

$doc = $dom->getElementsByTagName("html")->item(0);
$src = $xpath->query(".//@src");

foreach ( $src as $s ) {
  $s->nodeValue = array_pop( explode( "/", $s->nodeValue ) );
}

$output = $dom->saveXML( $doc );

echo $output;

它会输出以下内容:

<html>
  <body>
    <img src="test.jpg">
    <img src="test3.jpg">
    <video controls="controls" src="movie.ogg"></video>
  </body>
</html>

如果HTML嵌入到另一个HTML标签中,例如<script></script>,那么dom文档类就不是很有用。 - Ashesh
1
@Ashesh 我不是在跟随你。你向我们展示了 PHP 代码 - 我向你展示解决方案。 - Sampson
很抱歉,我应该更清楚地表达。这就是我所说的:"<html><head><script>var html = '<img src = /images/test.jpg/>'</script></head><body></html>"。在这种情况下,domdocument 将无法捕获 javascript 中的图像标签。这就是为什么我需要使用正则表达式的原因。 - Ashesh
@Ashesh 上面的代码将适用于您提供的PHP字符串。它将src元素转换为仅指向文件名。 - Sampson
有时候加载HTML解析器并不是一个好主意,特别是在短的预定义文本值上(例如<img alt="smth" src="smwhr"/>),其中只有src = ""和alt = ""可能会变化。 - BasTaller

1

你必须使用 e 修饰符。

$string = "<html><body><img src='images/test.jpg' /><img src='http://test.com/images/test3.jpg'/><video controls=\"controls\" src='../videos/movie.ogg'></video></body></html>";

$string2 = preg_replace("~src=[']([^']+)[']~e", '"src=\'" . convert_url("$1") . "\'"', $string);

请注意,在使用e修饰符时,替换脚本片段需要是一个字符串,以防止在调用preg_replace之前被解释。

1
function replace_img_src($img_tag) {
    $doc = new DOMDocument();
    $doc->loadHTML($img_tag);
    $tags = $doc->getElementsByTagName('img');
    foreach ($tags as $tag) {
        $old_src = $tag->getAttribute('src');
        $new_src_url = 'website.com/assets/'.$old_src;
        $tag->setAttribute('src', $new_src_url);
    }
    return $doc->saveHTML();
}

$img_tag 是什么? - roghayeh hosseini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接