簡體   English   中英

正則表達式從 Html 中刪除帶有樣式標簽的圖像

[英]Regex Remove Images with style tag from Html

我是 Regex 的新手,但我認為這是我需要做的事情的最簡單途徑。 基本上我有一個字符串(在 PHP 中),其中包含一整套 HTML 代碼......我想刪除任何具有 style=display:none 的標簽......

所以例如

<img src="" style="display:none" />

<img src="" style="width:11px;display: none" >

等等...

到目前為止,我的正則表達式是:

<img.*style=.*display.*:.*none;.* >

但這似乎留下了一些 html,並且在帶有 preg_replace 的 php 中使用時也會帶走下一個元素。

$html = preg_replace("/<img[^>]+style[^>]+none[^>]+>/", '', $html);

就像邁克爾指出的那樣,您不想為此目的使用正則表達式。 正則表達式不知道元素標簽是什么。 <foo>>foo<一樣有意義,除非你教它區別。 不過,教這種差異是非常乏味的。

DOM 更方便:

$html = <<< HTML
<img src="" style="display:none" />
<IMG src="" style="width:11px;display: none" >
<img src="" style="width:11px" >
HTML;

以上是我們的(無效)標記。 我們像這樣將它提供給 DOM:

$dom = new DOMDocument();
$dom->loadHtml($html);
$dom->normalizeDocument();

現在我們查詢包含文本“display”的“style”屬性的所有“IMG”元素的DOM。 我們可以在 XPath 中查詢“display: none”,但是我們的輸入標記出現了中間沒有空格的情況:

$xpath = new DOMXPath($dom);
foreach($xpath->query('//img[contains(@style, "display")]') as $node) {
    $style = str_replace(' ', '', $node->getAttribute('style'));
    if(strpos($style, 'display:none') !== FALSE) {
        $node->parentNode->removeChild($node);
    }
}

我們遍歷 IMG 節點並從它們的樣式屬性內容中刪除所有空格。 然后我們檢查它是否包含“display:none”,如果是,則從 DOM 中刪除該元素。

現在我們只需要保存我們的 HTML:

echo $dom->saveHTML();

給我們:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><img src="" style="width:11px"></body></html>

螺絲正則表達式!


附錄:您可能還對使用 CSS 選擇器解析 XML 文檔感興趣

因為<img>不允許在其中包含任何其他元素,所以這是可能的; 但總的來說,正則表達式對於解析像 HTML 這樣的遞歸定義語言來說是一個非常糟糕的工具。

無論如何,您可能遇到的問題是結束 > 正在與 .* 表達式之一匹配,並且恰好有一個稍后的 > 匹配您的顯式 > 。

如果您將所有 .* 替換為 [^>]* ,則會阻止這種情況。 (它們可能不需要全部更換,但您也可以)。

你的正則表達式太寬泛了; .*表示“匹配任何內容”,所以這將匹配:

<img src="foo.png" style="something">Some random displayed text : foo none; bar<br>

至少,您可能希望從匹配項中排除右括號,因此[^>]*而不是.* 不過,您可能還想閱讀這篇文章,並研究使用真正理解 HTML 的東西,例如DOMDocument

這是另一個適用於所有標簽的版本,包括在內聯樣式display:nonedisplay: none之間有空格的標簽。 另外它會刪除標簽內的內容。

$html = preg_replace('/<[^>]+style[^>]+display:\s*none[^>]+>.*?>/', '', $html);

所以我用以下方法測試了它,它工作正常。

Only show<div style='display:none'>Delete inside content as well</div> this text.

Only show<span style='display: none'>Delete inside content as well</span> this text.

Only show<div style="display: none">Delete inside content as well</div> this text.

Only show<span style="display:none;">Delete inside content as well</span> this text.

現在應該只輸出。

Only show this text.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM