Модераторы: Aliance, skyboy, MoLeX, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Регулярное выражение, удаление нутра тэга кроме комбинации  
:(
    Опции темы
Frozen_Coyote
Дата 15.10.2007, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 230
Регистрация: 20.9.2007

Репутация: нет
Всего: нет



Прошу помощи!

Есть тэг
<TD class=xl26 colSpan=5 style="BORDER-RIGHT: #ece9d8; BORDER-TOP: #ece9d8; BORDER-LEFT: #ece9d8; WIDTH: 272pt; BORDER-BOTTOM: #ece9d8; HEIGHT: 60pt; BACKGROUND-COLOR: transparent" width=363 >

нужно чтобы после TD вычищало все, кроме colspan=5. вместо 5 может быть двухзначное число. Вроде как то через исключение [^colspan=\d{1,2}] но четко не получается. помогите плиз.


PM MAIL   Вверх
sTa1kEr
Дата 16.10.2007, 07:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 5
Всего: 146



Цитата(Frozen_Coyote @  15.10.2007,  20:52 Найти цитируемый пост)
Вроде как то через исключение [^colspan=\d{1,2}]

Так нельзя писать, т.к. в квадратных скобках перечисляются символы, а не целковые фразы. Для этого используются Утверждения. Но можно и без утверждений обойтись.
Код

$str = '<TD class=xl26 colSpan=5 style="BORDER-RIGHT: #ece9d8; BORDER-TOP: #ece9d8; BORDER-LEFT: #ece9d8; WIDTH: 272pt; BORDER-BOTTOM: #ece9d8; HEIGHT: 60pt; BACKGROUND-COLOR: transparent" width=363 >';
echo preg_replace("/<td\s+[^>]*(colspan=(?(?='|\")('|\")\d+\\2|\d+\b))[^>]*>/is", "<td $1>", $str);

PM MAIL   Вверх
Frozen_Coyote
Дата 16.10.2007, 08:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 230
Регистрация: 20.9.2007

Репутация: нет
Всего: нет



Спасибо большое, отлично сработало, но если допустим в тэге colspan не присутствует - выражение оставляет его нетронутым. Я может некорректно выразился, но нужно чтобы выражение оставляло colspan если оно есть в тэге, если его нет - вычищало полностью, оставляя только <td>. наверно это надо через какие то хитрый preg_match делать?
PM MAIL   Вверх
SelenIT
Дата 16.10.2007, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 8
Всего: 401



Frozen_Coyote, попробуйте вот такую модификацию:
Код

echo preg_replace("/<td\s+[^>]*?((colspan=(?(?='|\")('|\")\d+\\3|\d+\b))[^>]*)?>/is", "<td $2>", $str);

Отличия от варианта sTa1kErа - еще одна пара скобок с "?" и минимизатор жаности первого "*".


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
Frozen_Coyote
Дата 16.10.2007, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 230
Регистрация: 20.9.2007

Репутация: нет
Всего: нет



Цитата(SelenIT @ 16.10.2007,  12:35)
Frozen_Coyote, попробуйте вот такую модификацию:
Код

echo preg_replace("/<td\s+[^>]*?((colspan=(?(?='|\")('|\")\d+\\3|\d+\b))[^>]*)?>/is", "<td $2>", $str);

Отличия от варианта sTa1kErа - еще одна пара скобок с "?" и минимизатор жаности первого "*".

Спасибо! Суперски! 

А можно еще попросить помочь: опять не могу сообразить: мне нужно чтобы выражение при нахождении в строке кроме colspan еще и  rowspan оставляло его также, для чего попробовал применить хитрый на мой взгляд способ, заменив в выражении в слове colspan c и l на точки (ну чтобы rowspan тоже цепляло). так вот: цепляет только один из двух находящихся в строке сопадений: если первый colspan - отобразит его (второй rowspan потрет) ну и наоборот. Подскажите, как заставить выражение в случае обнаружения обоих параметро оба и оставлять?

$Out = preg_replace("/<td\s+[^>]*?((\s.o.span=(?(?='|\")('|\")\d+\\3|\d+\b))[^>]*)?>/is", "<td$2>", $In);
PM MAIL   Вверх
sTa1kEr
Дата 17.10.2007, 08:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 5
Всего: 146



Frozen_Coyote, написал класс для. Производительность, конечно, немного пострадает, но зато универсальный.
Код

class Tags
{
   const patternTags = "/<([a-z]+\b)([^>]*)>/is";
   const patternAttribs = "/\s*(?(?=\b(%1\$s)\b)(\b[a-z]+=?(?(?='|\")('|\")[^\\3]+?\\3|\S+\b)\s?)
                                                |\b[a-z]+=?(?(?='|\")('|\")[^\\4]+?\\4|\S+\b)\s*)/isx";
   
   private static $_allows = array();

   public static function addAttribs(array $allows)
   {
      array_walk_recursive($allows, create_function('&$i,$k','$i=strtolower(preg_quote($i));'));
      self::$_allows = array_merge(self::$_allows, $allows);
   }

   public static function filterAttribs($string)
   {
      return preg_replace_callback(self::patternTags, array("self", "_removeAttribs"), $string);
   }

   private static function _removeAttribs($m)
   {
      $tag = strtolower($m[1]);
      if (!isset(self::$_allows[$tag]))
      {
         return $m[0];
      }
      else
      {
         $attrs = implode("|", self::$_allows[$tag]);
      }
      return "<$tag ".trim(preg_replace(sprintf(self::patternAttribs, $attrs), "$2", $m[2])).">";
   }  
}

// Пример
$str = '<TD rowspan="10" class=xl26 colSpan=5 style="BORDER-RIGHT: #ece9d8; BORDER-TOP: #ece9d8; BORDER-LEFT: #ece9d8; WIDTH: 272pt; BORDER-BOTTOM: #ece9d8; HEIGHT: 60pt; BACKGROUND-COLOR: transparent" width=363   >';
Tags::addAttribs(array("td" => array("colspan", "rowspan")));
echo Tags::filterAttribs($str);


Добавлено @ 08:48
Это для PHP 5.

Это сообщение отредактировал(а) sTa1kEr - 7.2.2008, 16:03
PM MAIL   Вверх
Frozen_Coyote
Дата 17.10.2007, 23:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 230
Регистрация: 20.9.2007

Репутация: нет
Всего: нет



sTa1kEr, огромное Вам спасибо за помощь. Очень признателен.
PM MAIL   Вверх
SelenIT
Дата 17.10.2007, 23:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 8
Всего: 401



sTa1kEr, красиво, впечатляет;). Одиночной регуляркой, насколько я понимаю, вопрос никак не решить (по крайней мере у меня, как я ни пробовал, не получилось)?

Пожалуй, preg_replace_callback действительно тут оптимум... вот только меня немного смущает лямбда-функция в цикле - если я ничего не путаю, в каких-то прежних версиях она создавалась заново при каждой итерации... в актуальных версиях это не так?


--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
sTa1kEr
Дата 18.10.2007, 07:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 5
Всего: 146



Цитата(SelenIT @  17.10.2007,  23:44 Найти цитируемый пост)
вот только меня немного смущает лямбда-функция в цикле - если я ничего не путаю, в каких-то прежних версиях она создавалась заново при каждой итерации... в актуальных версиях это не так? 

Эм... а где вы там цикл увидели? smile Она создается ровно столько раз, сколько вызван метод addAttribs(). Можно, конечно, ее вынести в отдельный метод или в статическое поле... но, имхо, на производительность это вообще не повлияет, а экономия ~1 кб памяти... 

PS Нашел ошибку в этой функции. Надо не возращать значение, а присваивать $i
Код

array_walk_recursive($allows, create_function('&$i,$k','$i=strtolower(preg_quote($i));'));

PM MAIL   Вверх
Frozen_Coyote
Дата 18.10.2007, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 230
Регистрация: 20.9.2007

Репутация: нет
Всего: нет



Господа, а как вам такой вот вариант я сделал? smile Что скажете? smile И вроде универсальный и к версии пхп не привязан, и четко отдупляет когда один rowspan или colspan, а когда - оба - и главное - раьотает же! smile


Код

$str = '<TD rowspan=10 class=xl26 colspan=5 style="BORDER-RIGHT: #ece9d8; BORDER-TOP: #ece9d8; BORDER-LEFT: #ece9d8; WIDTH: 272pt; BORDER-BOTTOM: #ece9d8; HEIGHT: 60pt; BACKGROUND-COLOR: transparent" width=363   >';


function DoIt($data)
{

$result = preg_match_all("/.o.span=\d{1,}/is", $data[0], $found);

if($result < 2)
{
$param= "<td $data[2]>";
}
else
{

$param = "<td ".$found[0][0]." ".$found[0][1].">";
}

return($param);


}

$str  = preg_replace_callback("/<td\s+[^>]*?(((.o.span)=(?(?='|\")('|\")\d+\\3|\d+\b))[^>]*)?>/is", "DoIt", $str );

echo $str;


Это сообщение отредактировал(а) skyboy - 15.12.2007, 01:03
PM MAIL   Вверх
SelenIT
Дата 19.10.2007, 01:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


баг форума
****


Профиль
Группа: Завсегдатай
Сообщений: 3996
Регистрация: 17.10.2006
Где: Pale Blue Dot

Репутация: 8
Всего: 401



Frozen_Coyote, весьма неплохо, только sTa1kErовские "навороты" в реге для перехвата значений атрибута вне зависимости от того, заключены ли они в какие-либо кавычки, уместны в ф-ции DoIt, а не в preg_replace_callback. Предлагаю уточненно-упрощенный вариант:
Код

$str = '<TD rowspan=10 class=xl26 colspan=5 rowspan="4" colspan=\'3\' notspan=66 width=363>';

function DoIt($data)
{
    $result = preg_match_all("/(row|col)span=(?(?='|\")('|\")\d+\\2|\d+\b)/is", $data[0], $found);
    return("<td ".implode(' ', $found[0]).">");
}

echo preg_replace_callback("/<td[^>]*>/is", "DoIt", $str);



--------------------
Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму!
PM MAIL   Вверх
Frozen_Coyote
Дата 19.10.2007, 07:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 230
Регистрация: 20.9.2007

Репутация: нет
Всего: нет



SelenIT, реально Ваш вариант лучше smile Спасибо! )
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Тексты | Следующая тема »


 




[ Время генерации скрипта: 0.1066 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.