2 回答

TA貢獻1942條經驗 獲得超3個贊
您可以使用交替來匹配src
or?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 >
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 />

TA貢獻1803條經驗 獲得超3個贊
這可以/應該用 DomDocument 來完成。
還值得一提的是,在用于訪問變異文檔時,將花括號添加到屬性字符串(它們被編碼)時會產生錯誤的副作用。saveHTML()
要解決此問題,請使用saveXML()
并刪除文檔前面的 xml 標記。
我將您的示例標簽包裝在父標簽中,以便 DomDocument 可以正常運行,而不會破壞您的文檔結構。這可能是您的項目不必要的預防措施。
我的代碼片段直接使用 XPath 定位符合條件的屬性,并在沒有任何正則表達式的情況下替換它們的值。我的 xpath 表達式中的豎線 (?|
) 表示“或”——因此它以 img 標簽的 src 屬性或鏈接標簽的 href 屬性為目標。
代碼:
$html = <<<HTML
<div>
? ? <img src="icons/example.svg">
? ? <a >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 >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
- 2 回答
- 0 關注
- 121 瀏覽
添加回答
舉報