preg_match атрибуты тегов

venetu

Мой дом здесь!
Регистрация
28 Мар 2007
Сообщения
745
Реакции
273
Вопрос мой скорее для раздела RegExps, но учитывая общий уровень нынешнего Нуледа, здесь единственный шанс, что кто-то ответит по теме. Потом можно будет перенести тред туда (если ответят!). Итак,

Мне нужно выцепить все style= из html. Не <style>..</style>, а именно значения атрибута style у всех тегов. Т.е. поймать всякие

<a style=border:0>
<table style= "padding:0; background:url('img.jpg') 0 0 no-repeat">
<div style=' font-face:"Times New Roman" '>
<div style =
"font-face:\"Times New Roman\"">
и т.д.

Строим регексп:

\s+ перед style обязательно стоит минимум один пробельный символ
style собственно слово "style"
\s*=\s* "равно", возможно разделенное пробельными символами

теперь дальше начинается шаманство:

["']? если начинается с кавычки, то мы должны дойти до конца пока не встретим такую же кавычку

если же открывающей кавычки не было - мы идем пока не найдем пробел, таб или закрывающий тег символ >

Дальше у нас собственно паттерн поиска, который зависит от предыдущего шага (Conditional subpattern). Т.е. мы ищем или
(1) такую же кавычку, или
(2) пробел или >

"Такая же" кавычка записывается как \1 - Back-reference на первую. Т.е. если начиналось на одинарную, то дальше мы ищем только одинарные, если начиналось с двойной - будем искать двойные. Здесь есть нюанс, что перед кавычкой не должно быть \ или их должно быть четное количество. Это можно записать как

[^\\](\\\\)*\1 т.е. не бекслеш, потом 0 или более пар бекслешей и \1 - "референс на предыдущую кавычку".

Если же паттерн не начинался с кавычек, то тут все просто

[^>\s]+ - не закрытие тега и не таб, пробел, перевод строки и другой пробельный символ.


Ну и в общем теперь, собственно, вопрос: помогите это все собрать в кучу.


PS: Пожалуйста не предлагайте DOMDocument, PHPQuery и пр. Я про них знаю, с ними данная задача решается элементарно.
 
мне кажется что нужно объять необъятное) если ещё теоритически можно встретит без кавычек, то при использовании слешей - получится невалидный html который скорее всего и работать не будет нигде.
Хотя вот что то накропал на ночь глядя-
PHP:
ob_start( );
?>
<style>
not
</style> 
 <a href="htp://1" style=border:1 class=""></a> 
 <a href="http://1" style="border:1" class=""></a>
 <a href="http://1" style = 'border:"2"'  class=""></a> 
 <a href="http://1" style = "border:\"3\" sss "  class=""></a>  
 <a href="http://1" style = "border:\\\"4\\\""  class=""></a>   
<?php
$e = ob_get_contents();
ob_end_clean();
preg_match_all('~\sstyle\s*=\s*([\'"])?
    (?(1)  
        ([^\\\]+?
            (
           (\\\ \1)
               |
           (\\\(\\\\\\\)* \1)
            )?
         )*?
        ((\\\\\\\)*)?
      \1 
      |
      (.*?)\s
    )~isx', $e, $html );
print_r($html);
посмотри, возможно какой нибуть случай не учёл. + есть предположение что дум парсеры не используются из-за скорости, я не уверен что это выражение будет очень быстрым- есть вариант найти все строки style=[^>]*?> и посимвольно разобрать из в пхп.
 
Назад
Сверху