Я новичок в Regex, однако я решил, что это самый простой путь к тому, что мне нужно было сделать. В основном у меня есть строка (в PHP), которая содержит весь код HTML-кода … Я хочу удалить любые теги, которые имеют стиль = display: none …
так, например,
<img src="" style="display:none" />
<img src="" style="width:11px;display: none" >
и т.д…
Пока мое Regex:
<img.*style=.*display.*:.*none;.* >
Но это, кажется, оставляет бит html позади, а также убирает следующий элемент при использовании в php с preg_replace.
Как указал Майкл , вы не хотите использовать Regex для этой цели. Regex не знает, что такое тег элемента. <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();
Теперь мы запрашиваем DOM для всех элементов «IMG», содержащих атрибут «style», который содержит текст «display». Мы могли запросить «display: none» в XPath, но наша разметка ввода имеет вхождения без пробела между ними:
$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>
Винт Regex!
Приложение: вас также может заинтересовать оформление XML-документов с помощью селекторов CSS
$html = preg_replace("/<img[^>]+style[^>]+none[^>]+>/", '', $html);
Поскольку <img>
не допускает никаких других элементов внутри него, это возможно; но в общем случае regexp является очень плохим инструментом для анализа рекурсивно определенного языка, такого как HTML.
Во всяком случае, проблема, с которой вы, вероятно, сталкиваетесь, заключается в том, что закрытие> соответствует одному из выражений. *, И, оказывается, будет более поздняя строка> в строке, соответствующая вашему явному значению>.
Если вы замените все ваши. * На [^>] *, что предотвратит это. (Они, вероятно, не все должны быть заменены, но вы также можете).
Ваше регулярное выражение слишком широкое; .*
означает «соответствовать чему-либо», поэтому это будет соответствовать:
<img src="foo.png" style="something">Some random displayed text : foo none; bar<br>
По крайней мере, вы, вероятно, хотите исключить закрывающие скобки из своих совпадений, поэтому [^>]*
вместо .*
. Вы также можете прочитать это , и изучите использование того, что действительно понимает HTML, например DOMDocument