Псевдо-XML
// 3 декабря 2002 годаСейчас пробую сделать
Нашел в Сети вот это. Простая функция, которая «…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;
}
Регулярные выражения рулят, но…
А теперь сюрприз! Если пожертвовать «универсальностью» (например, выдачей текста в виде arrayа или нечувствительностью к регистру тэгов), то можно сделать так, чтобы эта функция работала в восемь раз быстрее.
Таким вот образом
function tags ($string, $tag)
{
$z=strpos ($string, "<".$tag.">")+strlen ($tag)+2;
$s=substr ($string, $z, strpos ($string, "</".$tag.">")-$z);
return $s;
}
Итого: 1) Можно использовать обе функции, первую когда надо получить именно array, вторую когда надо получить только
Применение: для движков сайтов. Например, дату можно писать как <date>32 мартобря</date> в любом месте текста. А потом выкусывать с помощью этой функции. Получаем что и хотели
Для полноты картины добавим обработку ошибок (если ничего не найдено):
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) Шушпанов Пётр Анатольевич function xmf($string, $tag) { $string = ' function tags($string) { function xmf($string, $tag) { print_r($xmf);<?
// mail: web@phystech.ru
// Очередной вариант: теперь может вырезать контент из тэгов с параметрами, типа <p class=...>...</p>, <td ...>...</td>.
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" (ИксЭмЭль импровизированный) :)
<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);
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;
}
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;
}
?>