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

我试图用一个小的修改来替换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


任何想法?提前致谢


收到一只叮咚
浏览 94回答 2
2回答

手掌心

您可以使用交替来匹配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> tagecho 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"/>

繁星点点滴滴

这可以/应该用 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="http://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="http://www.example.com/default.htm"/></div>哎呀,我刚刚看到你问题中的最后一个请求。not()和的实现 starts-with()应用于两个标签,以取消已经转换为小胡子代码的元素的资格。新的 xpath 表达式://img[not(starts-with(@src,"{{asset"))]/@src | //link[not(starts-with(@href,"{{asset"))]/@href
打开App,查看更多内容
随时随地看视频慕课网APP