preg_replace img src 到 data-src 堆栈溢出 (PHP)
preg_replace img src to data-src stack overflow (PHP)
我为 iframe 使用了延迟加载脚本,我需要制作一个 preg_replace 代码来将 src 更改为 data-src。
我试过类似的方法但我失败了:
$cache = preg_replace('%<iframe.*?src=["\'](.*?)["\'].*?/?>%i', 'data-src=""', $content);
我的代码只打印 data-src="the link"
而没有完整的 iframe 代码。
新答案使用合法 DOM 解析函数来可靠地变异有效 html:
- 迭代所有 iframe 标记。
- 使用现有
src
属性插入新的 data-src
属性。
- 删除旧的
src
属性。
- 打印更新后的 DOM。
如@user706420 所述,从 <iframe>
标记中删除 src
属性是一个错误的决定,因为它会使 html 无效。我的回答是关于如何执行标签属性替换的示范,但我同意@user706420 的观点,这个任务在逻辑上确实存在缺陷。
代码:(Demo)
$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();
输出:
<p>Some random text <iframe width="425" height="350" frameborder="0" data-src="the link"></iframe></p>
旧答案(2020 年 10 月 9 日改进)和我不再认可的建议,因为正则表达式是“DOM-无知”...
匹配 <iframe
的开头和起始标记中的所有字符,直到遇到紧跟子字符串 src=
的 space 字符——这确保了目标 src=
子字符串前面没有任何非白色 space 字符(换句话说,它是一个 whole/solitary 字)。
space 之前的子字符串必须是 released/forgotten -- 这就是 \K
所做的。 space 将需要消耗并替换为 data-
。
代码:(Demo)
$content = 'Some text that contains src <iframe src="www.example.com"/> Some text';
echo preg_replace('~<iframe[^>]*\K (?=src=)~i', ' data-', $content);
输出:
Some text that contains src <iframe data-src="www.example.com"/> Some text
虽然我改进了正则表达式,但可以看到有效的 html 字符串被故意写入以破坏正则表达式,例如: <iframe src="www.example.com"/ data-type="<iframe" data-whoops=" src= oh my"> 因此,我只建议使用 html 解析dom 解析器。
我为 iframe 使用了延迟加载脚本,我需要制作一个 preg_replace 代码来将 src 更改为 data-src。
我试过类似的方法但我失败了:
$cache = preg_replace('%<iframe.*?src=["\'](.*?)["\'].*?/?>%i', 'data-src=""', $content);
我的代码只打印 data-src="the link"
而没有完整的 iframe 代码。
新答案使用合法 DOM 解析函数来可靠地变异有效 html:
- 迭代所有 iframe 标记。
- 使用现有
src
属性插入新的data-src
属性。 - 删除旧的
src
属性。 - 打印更新后的 DOM。
如@user706420 所述,从 <iframe>
标记中删除 src
属性是一个错误的决定,因为它会使 html 无效。我的回答是关于如何执行标签属性替换的示范,但我同意@user706420 的观点,这个任务在逻辑上确实存在缺陷。
代码:(Demo)
$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();
输出:
<p>Some random text <iframe width="425" height="350" frameborder="0" data-src="the link"></iframe></p>
旧答案(2020 年 10 月 9 日改进)和我不再认可的建议,因为正则表达式是“DOM-无知”...
匹配 <iframe
的开头和起始标记中的所有字符,直到遇到紧跟子字符串 src=
的 space 字符——这确保了目标 src=
子字符串前面没有任何非白色 space 字符(换句话说,它是一个 whole/solitary 字)。
space 之前的子字符串必须是 released/forgotten -- 这就是 \K
所做的。 space 将需要消耗并替换为 data-
。
代码:(Demo)
$content = 'Some text that contains src <iframe src="www.example.com"/> Some text';
echo preg_replace('~<iframe[^>]*\K (?=src=)~i', ' data-', $content);
输出:
Some text that contains src <iframe data-src="www.example.com"/> Some text
虽然我改进了正则表达式,但可以看到有效的 html 字符串被故意写入以破坏正则表达式,例如: <iframe src="www.example.com"/ data-type="<iframe" data-whoops=" src= oh my"> 因此,我只建议使用 html 解析dom 解析器。