Вы не предоставили образец ввода для использования, но вы упомянули, что имеете дело с html. Это должно звучать как сигнал тревоги, что использование регулярных выражений в качестве прямого решения не рекомендуется. Когда вы намереваетесь обработать действительный html, вы должны использовать синтаксический анализатор dom для изоляции атрибутов стиля.
Почему бы вам не использовать регулярные выражения для изоляции объявлений встроенного стиля? Проще говоря: Regex является "не подозревающим об этом". Он не знает, когда он находится внутри или снаружи тега (я предоставлю в своей демонстрации придуманный гаечный ключ, чтобы выразить эту уязвимость. Кроме того, используя синтаксический анализатор dom добавит преимущество правильной обработки различных типов цитирования. Хотя регулярное выражение может быть написано для сопоставления / подтверждения сбалансированного цитирования, оно добавляет значительное раздувание (при правильном выполнении) и ухудшает читабельность и удобство обслуживания вашего сценария.
В моей демонстрации я покажу, как можно просто / точно очистить пробелы после двоеточий, точек с запятой и запятых после выделения истинных встроенных объявлений стилей. Я пошел немного дальше (поскольку на этой странице было упомянуто сгущение цветового шестнадцатеричного кода), чтобы показать, как можно использовать регулярное выражение, чтобы уменьшить некоторые шестизначные шестнадцатеричные коды до трех символов.
Код: ( Демо )
$html = <<<HTML
<div style='font-family: "Times New Roman", Georgia, serif; background-color: #ffffff; '>
<p>Some text
<span class="ohyeah" style="font-weight: bold; color: #ff6633 !important; border: solid 1px grey;">
Monkeywrench: style="padding: 3px;"
</span>
&
<strong style="text-decoration: underline; ">Underlined</strong>
</p>
<h1 style="margin: 1px 2px 3px 4px;">Heading</h1>
<span style="background-image: url('images/not_a_hexcode_ffffff.png'); ">Text</span>
</div>
HTML;
$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
foreach ($dom->getElementsByTagName('*') as $node) {
$style = $node->getAttribute('style');
if ($style) {
$patterns = ['~[:;,]\K\s+~', '~#\K([\da-f])\1([\da-f])\2([\da-f])\3~i'];
$replaces = ['', '\1\2\3'];
$node->setAttribute('style', preg_replace($patterns, $replaces, $style));
}
}
$html = $dom->saveHtml();
echo $html;
Выход:
<div style='font-family:"Times New Roman",Georgia,serif;background-color:#fff;'>
<p>Some text
<span class="ohyeah" style="font-weight:bold;color:#f63 !important;border:solid 1px grey;">
Monkeywrench: style="padding: 3px;"
</span>
&
<strong style="text-decoration:underline;">Underlined</strong>
</p>
<h1 style="margin:1px 2px 3px 4px;">Heading</h1>
<span style="background-image:url('images/not_a_hexcode_ffffff.png');">Text</span>
</div>
Приведенный выше фрагмент использует \K
в шаблонах, чтобы избежать использования обходных групп и лишних групп захвата.
Я не пишу шаблон, который удаляет пробел до !important
, потому что я прочитал некоторые (не очень свежие) посты, в которых некоторые браузеры выражают ошибочное поведение без пробела.