为了账号安全,请及时绑定邮箱和手机立即绑定

如何用小胡子表达式替换文档中的 img src 和 link href?

如何用小胡子表达式替换文档中的 img src 和 link href?

PHP
收到一只叮咚 2023-04-15 20:16:19
我试图用一个小的修改来替换src,值hrefregex简单例子//Find:<img src="icons/google-icon.svg" > //Replace to: <img src="{{asset('icons/google-icon.svg')}}" >//Find:<link href="css/style.css"> //Replace to: <link href="{{asset('css/style.css')}}">/** etc... */现在这是我的正则表达式://Find:src\s*=\s*"(.+?)" //Replace to:src="{{ asset('$1') }}"它的工作实际上非常好,但它只适用于src不 [ href,src],我也想排除包含的任何值{{asset任何想法?提前致谢
查看完整描述

2 回答

?
手掌心

TA贡献1942条经验 获得超3个赞

您可以使用交替来匹配srcor href,然后使用否定前瞻来断言 src/href 不以 开头{{asset

((?:src|href)\s*=\s*")((?!{{\s*asset)[^"]+)

这也将更改标签href<a>或其他地方的属性。如果这是一个问题,请改用DOMDocument解决方案。请注意,如果您的 HTML 不仅仅是一个片段,那么您不需要div在对的调用中在其周围添加标记loadHTML,并且最后一行应更改为echo substr($doc->saveXML(), 38);.

$html = <<<EOT

//Find:

<img src="icons/google-icon.svg" > 

//Replace to: 

<img src="{{asset('icons/google-icon.svg')}}" >


//Find:

<link href="css/style.css"> 

//Replace to: 

<link href="{{asset('css/style.css')}}">

/** etc... */

<a href="http://www.example.com">

EOT;


$doc = new DOMDocument();

$doc->loadHTML("<div>$html</div>", LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);


$xpath = new DOMXPath($doc);

foreach ($xpath->query('//img') as $img) {

    $src = $img->getAttribute('src');

    if (preg_match('/^(?!{{\s*asset).*$/', $src, $m)) {

        $img->setAttribute('src', "{{asset('" . $m[0] . ")'}}");

    }

}


foreach ($xpath->query('//link') as $link) {

    $href = $link->getAttribute('href');

    if (preg_match('/^(?!{{\s*asset).*$/', $href, $m)) {

        $link->setAttribute('href', "{{asset('" . $m[0] . ")'}}");

    }

}


// strip XML header and added <div> tag

echo substr($doc->saveXML(), 44, -6);

输出:


//Find:

<img src="{{asset('icons/google-icon.svg)'}}"/> 

//Replace to: 

<img src="{{asset('icons/google-icon.svg')}}"/>


//Find:

<link href="{{asset('css/style.css)'}}"/> 

//Replace to: 

<link href="{{asset('css/style.css')}}"/>

/** etc... */

<a href="http://www.example.com"/>


查看完整回答
反对 回复 2023-04-15
?
繁星点点滴滴

TA贡献1803条经验 获得超3个赞

这可以/应该用 DomDocument 来完成。

还值得一提的是,在用于访问变异文档时,将花括号添加到属性字符串(它们被编码)时会产生错误的副作用。saveHTML()要解决此问题,请使用saveXML()并删除文档前面的 xml 标记。

我将您的示例标签包装在父标签中,以便 DomDocument 可以正常运行,而不会破坏您的文档结构。这可能是您的项目不必要的预防措施。

我的代码片段直接使用 XPath 定位符合条件的属性,并在没有任何正则表达式的情况下替换它们的值。我的 xpath 表达式中的竖线 ( |) 表示“或”——因此它以 img 标签的 src 属性或链接标签的 href 属性为目标。

代码:

$html = <<<HTML

<div>

    <img src="icons/example.svg">

    <a href="http://www.example.com">a link</a>

    <link href="css/example.css">

    <iframe src="//www.example.com/default.htm"></iframe>

</div>

HTML;


$dom = new DOMDocument();

$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

$xpath = new DOMXPath($dom);

foreach ($xpath->query('//img/@src | //link/@href') as $attr) {

    $attr->value = "{{asset('" . $attr->value . "')}}";

}

echo substr($dom->saveXML(), 38);  // remove the auto-generated xml tag from the start

输出:


<div>

    <img src="{{asset('icons/example.svg')}}"/>

    <a href="http://www.example.com">a link</a>

    <link href="{{asset('css/example.css')}}"/>

    <iframe src="//www.example.com/default.htm"/>

</div>

哎呀,我刚刚看到你问题中的最后一个请求。

not()和的实现 starts-with()应用于两个标签,以取消已经转换为小胡子代码的元素的资格。

新的 xpath 表达式:

//img[not(starts-with(@src,"{{asset"))]/@src | //link[not(starts-with(@href,"{{asset"))]/@href



查看完整回答
反对 回复 2023-04-15
  • 2 回答
  • 0 关注
  • 74 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信