За последние 24 часа нас посетили 16934 программиста и 1272 робота. Сейчас ищут 1487 программистов ...

Заменить: (такого_нет)(Такое_есть)

Тема в разделе "Регулярные выражения", создана пользователем Kreker, 17 апр 2008.

  1. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Имеется html-код.
    HTML:
    1. <span style="text-decoration: underline;"><span style="font-style: italic;"><span style="font-weight: bold;">text1</span></span>text2</span>
    Текст 1 - жирный подчеркнутый курсив
    Текст 2 - подчеркнутый
    Задача - убрать кашу и объединить сдвоенные теги.

    Вариант 1 - взять примитивную регулярку:
    PHP:
    1.  
    2. <?php
    3. preg_replace('~<span\sstyle="(.*?)"><span\sstyle="(.*?)">(.*?)</span></span>~is', '<span style="$1 $2">$3</span>', $text);
    4. ?>
    Она не верная по причинам:
    а) ищет первые 2 внешних тега, а не внутренних. После её работы текст 2 получается не только подчеркнутым, но и курсивным:
    HTML:
    1.  
    2. <span style="text-decoration: underline; font-style: italic;"><span style="font-weight: bold">text1</span>text2</span>
    3.  
    б) Почему-то иногда вставляет в стиль тегов font, div (в некоторых местах и не в конкретном примере (в тестируемом мног кода)) - загадка для меня.

    Вариант 2
    При парсинге смотреть, нет ли внутри тегов span, но регулярка не работает - текст не изменяется.
    PHP:
    1.  
    2. <?php
    3. preg_replace('~<span\sstyle="(.*?)"><span\sstyle="(.*?)">(^(?:<span(.*?)>)&(.*?))</span></span>~is', '<span style="$1 $2">$3</span>', $text);
    4. ?>
    Надо как-то объединить условия поиска. Амперсдант, видимо, не подходит.

    Помогите, пожалуйста.
     
  2. RomanBush

    RomanBush Активный пользователь

    С нами с:
    5 дек 2007
    Сообщения:
    798
    Симпатии:
    0
    Адрес:
    200 км от Москвы
    http://weitz.de/regex-coach/ - прога, для "подбора" регулярок.
    Всё, чем могу. Сам сейчас посидел минут 20 - есть несколько вариантов, как можно выдрать, но универсальный не получается. Так что сам попробуй.
     
  3. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    RomanBush
    Спасибо за линк, сейчас потестим.
     
  4. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    У span'ов только style?
     
  5. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Sergey89
    Да. Они приходят от визуального редактора.

    Вообще, у меня есть вариант на запасе - искать preg_match_all, а потом уже РНР разбирать, но хотелось бы одной регуляркой заменять.
     
  6. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Я - мутант.
    Регулярки нужной так и не нашел, но получилось вот что:
    PHP:
    1.  
    2. <?php
    3.     function optimize_span($result) {
    4.             $result = preg_replace('~<span\sstyle="(?:[\#a-zA-Z\:\;\s\-]+)">(\\s|&nbsp)*?</span>~is', '', $result);
    5. preg_match_all('~<span\sstyle="(?:[\#a-zA-Z\:\;\s\-]+)"><span\sstyle="(?:[\#a-zA-Z\:\;\s\-]+)">(?:.*?)</span></span>~is',  $result, $matches);
    6.         $smatches = sizeof($matches[0]);
    7.         for ($i = 0; $i < $smatches; $i++) {
    8.             preg_match_all('~<span\sstyle="(.+?)">~is',  $matches[0][$i], $match2);
    9.             $size = sizeof($match2[0]) -1;
    10.             $patt = $match2[0][($size-1)].$match2[0][($size)];
    11.             $string = strtr($matches[0][$i], Array($patt => '<span style="'.$match2[1][($size-1)].' '.$match2[1][($size)].'">', "</span></span>" => "</span>")) ;
    12.             $result = strtr($result, Array($matches[0][$i] => $string)) ;
    13.         }
    14.         return $result;
    15.     }
    16.  
    Три-четыре вызова этой функции превращают это:

    HTML:
    1.  
    2. <span style="font-weight: bold;">asdasd <span style="font-style: italic;">asdasd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="text-decoration: underline;">adasdasda<br />dsad<br /><br /></span></span></span><div style="text-align: right;"><span style="font-weight: bold;"><span style="font-style: italic;"><span style="text-decoration: underline;"><span style="color: #ffffff;">asdasd<br /></span></span></span></span><div style="text-align: left;"><span style="font-weight: bold;"><font style="color: rgb(255, 0, 0);" size="4"><span style="font-weight: bold;">dvsvs<br />&nbsp;</span></font></span><font style="color: rgb(255, 140, 0);" size="4"><font size="3">asfaf<br /></font></font><div style="text-align: center;"><span style="font-family: Comic Sans MS;">bcvb<br /><br /><a href="http://ya.ru">dasdad</a><br /><br /></span><div style="text-align: left;"><ul><li>csc</li><li>gj</li></ul><img src="http://kreker.org/2.gif"><br /></div></div><span style="font-weight: bold;"><span style="font-style: italic;"><span style="text-decoration: underline;"></span></span></span></div><span style="font-weight: bold;"><span style="font-style: italic;"><span style="text-decoration: underline;"></span></span></span></div>asdas
    3.  
    В это:
    HTML:
    1.  
    2. <span style="font-weight: bold;">asdasd <span style="font-style: italic;">asdasd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="text-decoration: underline;">adasdasda<br />dsad<br /><br /></span></span></span><div style="text-align: right;"><span style="font-weight: bold; font-style: italic; text-decoration: underline; color: #ffffff;">asdasd<br /></span><div style="text-align: left;"><span style="font-weight: bold;"><font style="color: rgb(255, 0, 0);" size="4"><span style="font-weight: bold;">dvsvs<br />&nbsp;</span></font></span><font style="color: rgb(255, 140, 0);" size="4"><font size="3">asfaf<br /></font></font><div style="text-align: center;"><span style="font-family: Comic Sans MS;">bcvb<br /><br /><a href="http://ya.ru">dasdad</a><br /><br /></span><div style="text-align: left;"><ul><li>csc</li><li>gj</li></ul><img src="http://kreker.org/2.gif"><br /></div></div></div></div>asdas
    3.  
    Сразу говорю, производительность не важна в данном случае - это "чистка" визуального редактора админ-панели.