【问题标题】:preg_replace img src to data-src stack overflow (PHP)preg_replace img src 到 data-src 堆栈溢出 (PHP)
【发布时间】:2017-11-29 05:10:19
【问题描述】:

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

我尝试了类似的方法,但失败了:

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

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

【问题讨论】:

    标签: php html iframe preg-replace


    【解决方案1】:

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

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

    正如@user706420 所述,从&lt;iframe&gt; 标记中删除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-ignorant”...

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

    必须释放/忘记空格之前的子字符串——这就是\K 所做的。该空间将需要被消耗并替换为 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"> 因此,我只建议使用 dom 解析器解析 html。

    【讨论】:

    • 这是一个错误。像 /embed/CsRcybaSXLc 这样的 Youtube 网址中包含“sRc”。您的代码将其捕获并将其替换为 /embed/Cdata-sRcybaSXLc 也许应该是 (?=src=) 在此处测试 regex101.com/r/DHlZCC/1
    • 这个答案很糟糕,绝不提供我目前给出的建议。我今天将重写这个答案,以使用 DOM 解析器和合法的 DOM 操作函数调用。谢谢你吹口哨。我有点尴尬。
    • @user706420 我已经更新了我的答案。再次感谢。
    • 不错的更新。 :) 旧答案仍然有错误。我在这里使用 (?=src=) ;) 我将此代码用于图像 '~]*\K(?=src=)~i', 'src="data:," data-' 删除src 属性对于 不是一个好的选择,因为没有 src 属性的 html 是无效的。因此,我将其替换为有效的 html 'src="data:," data-x'
    • @user 我已经改进了正则表达式模式,超出了您的建议,然后故意编写了一个 html 字符串,故意破坏该模式以证明不应该信任正则表达式来解析 html。
    猜你喜欢
    • 1970-01-01
    • 2017-12-13
    • 1970-01-01
    • 1970-01-01
    • 2014-01-09
    • 2011-07-21
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多