Вы сейчас здесь
«Облако» тэгов
link, small, tagless, tiny, 2003, big, 2008, 2010, январь, декабрь, сентябрь, 2001, 2004, 2002, август, март, апрель, июль, 2009, игры, октябрь, май, июнь, февраль, 2007, ноябрь, img, 2011, quote, wow, huge, блоги, кино, игровой дизайн, ребенок, половой вопрос, технологии, lytdybr, вебдев, фразы, живой журнал, жизнь, яндекс, язык, php, людишки, 2006, 2005, software, поисковики, video, inglish, 2000, смишно, диалоги, музыка, книги, культ личности, политика, дейтинг, интернет, 1999, rss, контент, flash, реклама, я, авторские проекты, next-gen mmo, прон, ореховые скорлупки, сми, 2012, js, программирование, fight club, register, социгры, спам, english reviews, iphone, потребление, американас, идеи, беллетристика, мое величие, usability, пидорасты, battle.net, lifestyle, starcraft 2, Тёма, соционика, spectator.ru, британские ученые, развитие, Масква, фото, бабло, литература, mobile, work, болкман, титаны, hard, hobius, mysql, интеллектуальный юмор, хостинг, blogowar.ru, графика, SEO, blogowar, magic, журналистика, злоба дня, религия, стартапы, social, tf2, браузеры, цитаты, gzip, warhammer, велосипед, киви, медикаментоз, общество, оговорки, html, воспитание, мифы, паранойа, письма в редакцию, учеба, 1998, mongodb, soft, soviet, twdnkumus, глянцевые журналы, монетизация, норкотики, сайты, сиськи, типографика, тьюринг, дизайн, железо, живут же люди, лолвут, плагиат, твиттер, еда, тренд, about, бабушки, вещи, видео, зомбоящик, игрушки, социопатия,
Персональное
об авторе и сайте
мойкруг (резюме)
на G+
порнотумблер (rss)
инстаграм (хипстерские фото)

facebook
twitter

skype: acerbial
gtalk: dmitry.smirnov


C любовью к людишкам™,
♥ 1998 - 2013.

powered by mongodb.



Псевдо-XML

Сейчас пробую сделать что-то типа псевдо-xml. Никаких модулей у хостера не стоит, поэтому приходится разбирать все «вручную» с помощью PHP.

Нашел в Сети вот это. Простая функция, которая «...extracts the content of all tags ($tag) in string ($string). When ($mode) is 1 it returns the content as an array, otherwise as a string». То есть вы пишите $quotetext=untag ($string, "blockquote", 0) и получаете текст, который заключен в <blockquote>этот тэг</blockquote>.


function untag ($string, $tag, $mode)
{
$tmpval="";
$preg="/<".$tag.">(.*?)</".$tag.">/si";
preg_match_all ($preg,$string,$tags);
foreach ($tags[1] as $tmpcont) {
if ($mode==1){$tmpval[]=$tmpcont;}
else {$tmpval.=$tmpcont;}
}
return $tmpval;
}

Регулярные выражения рулят, но... KISS-принцип гласит: «Keep It Simple, Stupid». Очень часто можно обойтись без регулярных выражений, используя функции, которые работают быстрее. Это известная фишка — что strpos работает очень быстро и в некоторых случаях может запросто заменить некоторые регулярные выражения.

А теперь — сюрприз! Если пожертвовать «универсальностью» (например, выдачей текста в виде array’а или нечувствительностью к регистру тэгов), то можно сделать так, чтобы эта функция работала в восемь раз быстрее.

Таким вот образом —

function tags ($string, $tag)
{
$z=strpos ($string, "<".$tag.">")+strlen ($tag)+2;
$s=substr ($string, $z, strpos ($string, "</".$tag.">")-$z);
return $s;
}

Итого: 1) Можно использовать обе функции, первую — когда надо получить именно array, вторую — когда надо получить только 1-ое вхождение и вы точно знаете, в каком регистре пишутся тэги. 2) Часто можно обойтись без регулярных выражений.

Применение: для движков сайтов. Например, дату можно писать как <date>32 мартобря</date> в любом месте текста. А потом выкусывать с помощью этой функции. Получаем что и хотели — «псевдо-ХМL».

Для полноты картины добавим обработку ошибок (если ничего не найдено):


function untag ($string, $tag)
{
$z = strpos ($string, '<'.$tag.'>');
if ($z!==false) {
$z=$z+ strlen ($tag) + 2;
$z2 = strpos ($string, '</'.$tag.'>');
$s = substr ($string, $z, $z2 - $z);
return $s;
}
};

Для тех, кто в танке! В комментариях к данной заметке нашелся умник, который хочет «всего-лишь показать, что главный недостаток регулярных выражений — нежелание в них разбираться». При этом предлагает свой пример, который работает как минимум в шесть раз медленней. Что критично. Уважаемый! Главный недостаток регулярных выражений — это то, что некоторые люди, которые «разобрались» в регулярных выражениях, пихают их куда ни попадя.

Update: От читателя пришел апдейт этой функции. Теперь она может вырезать тэги с параметрами, типа <td ...>...</td> и складывать содержимое одинаковых тэгов в array.

<?

// (C) Шушпанов Пётр Анатольевич
// mail: web@phystech.ru
// Очередной вариант: теперь может вырезать контент из тэгов с параметрами, типа <p class=...>...</p>, <td ...>...</td>.

function xmf($string, $tag) {
while(true):
//начало тэга
$start = strpos($string, "<".$tag, $stop);
if ($start === false)
break;
//начало контента
$start = strpos($string, ">", $start);
if ($start === false)
break;
$start++;
//конец контента
$stop = strpos($string, "</".$tag.">", $start);
if ($stop === false)
break;
//выкусить контент!
$result[] = substr($string, $start, $stop - $start);
endwhile;
return $result;
}


// Далее можно ещё тем же методом выковырять все тэги автоматически, а
// потом весь контент распихать в массив поименованый тэгами. У меня на машине
// такой скриптех выполняется .00011 с
// А функцию я назвал XMF - "XML Fake" (ИксЭмЭль импровизированный) :)

$string = '
<news>один</news>
<news>два</news>
<news>три</news>
<news>четыре</news>
<menu>a</menu>
<menu>b</menu>
<menu>c</menu>
<menu>d</menu>
<title>aaaa</title>';


$tags = tags($string);
foreach ($tags as $val)
$xmf[$val] = xmf($string, $val);

function tags($string) {
while(true):
$start = strpos($string, '<', $stop);
if ($start === false)
break;
$start = $start + strlen($tag) + 1;
$stop = strpos($string, '>', $start);
if ($stop === false)
break;
$res = substr($string, $start, $stop - $start);
if (strpos($res, '/') === false && !in_array($res,(array)$result)):
$result[] = $res;
endif;
endwhile;
return $result;
}

function xmf($string, $tag) {
while(true):
$start = strpos($string, "<".$tag.">", $stop);
if ($start === false)
break;
$start = $start + strlen($tag) + 2;
$stop = strpos($string, "</".$tag.">", $start);
if ($stop === false)
break;
$result[] = substr($string, $start, $stop - $start);
endwhile;
return $result;
}

print_r($xmf);
?>

0
Привет, Anonymous! Чтобы оставлять комментарии, надо авторизоваться.