preg_replace img src 到 data-src 堆栈溢出 (PHP)

sad*_*dad 2 html php iframe preg-replace

我对 iframe 使用延迟加载脚本,我需要制作 preg_replace 代码以将 src 更改为 data-src。

我尝试了这样的事情但我失败了:

$cache = preg_replace('%<iframe.*?src=["\'](.*?)["\'].*?/?>%i', 'data-src="$1"', $content);
Run Code Online (Sandbox Code Playgroud)

我的代码仅打印,data-src="the link"没有完整的 iframe 代码。

mic*_*usa 5

新答案使用合法的 DOM 解析函数来可靠地改变有效的 html:

  • 迭代所有 iframe 标签。
  • data-src使用现有属性插入新属性src
  • 删除旧src属性。
  • 打印更新后的 DOM。

正如 @user706420 所提到的,src<iframe>标签中删除该属性是一个错误的决定,因为它会使 html 无效。我的回答是关于如何执行标签属性替换的说明性的,但我同意@user706420的观点,即这个任务似乎在逻辑上有缺陷。

代码:(演示

$html = <<<HTML
<p>Some random text <iframe src="the link"" width="425" height="350" frameborder="0"></iframe></p>
HTML;

libxml_use_internal_errors(true);
$dom = new DOMDocument;
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
foreach ($dom->getElementsByTagName('iframe') as $iframe) {
    $iframe->setAttribute('data-src', $iframe->getAttribute('src'));
    $iframe->removeAttribute('src');
}
echo $dom->saveHTML();
Run Code Online (Sandbox Code Playgroud)

输出:

<p>Some random text <iframe width="425" height="350" frameborder="0" data-src="the link"></iframe></p>
Run Code Online (Sandbox Code Playgroud)

旧答案(于 2020 年 10 月 9 日改进)以及我不再认可的建议,因为正则表达式是“DOM-ignorant”......

匹配开始<iframe标记中的所有字符,直到遇到紧跟子字符串的空格字符src=- 这确保目标子src=字符串没有任何前面的非空白字符(IOW,它是一个完整的/单独的词)。

空格之前的子字符串必须被释放/忘记——这就是\K所做的。该空间需要被消耗并替换为 data-

代码:(演示

$content = 'Some text that contains src <iframe src="www.example.com"/> Some text';
echo preg_replace('~<iframe[^>]*\K (?=src=)~i', ' data-', $content);
Run Code Online (Sandbox Code Playgroud)

输出:

Some text that contains src <iframe data-src="www.example.com"/> Some text
Run Code Online (Sandbox Code Playgroud)

虽然我改进了正则表达式,但可以看到故意写入有效的 html 字符串来破坏正则表达式,例如:<iframe src="www.example.com"/ data-type="<iframe" data-whoops=" src= oh my ">因此,我只建议使用 dom 解析器来解析 html。