клуб PHP
клуб заведен 16-03-2003
постоянные читатели [14]
501, Arm0, cadaver, Dark, Delia Grey, diteX, Genux, LinkMan, Query, Santail, Svetlika, Urkagan, wanglo, zar
хранители [1]
zar
участники [15]
501, Alick, Arm0, Azimmers, cadaver, d-r Hogart, d0Xt0r, Delia Grey, diteX, maybe_we, Query, Santail, wanglo, zar, Звёздный Капитан
закладки:
цитатник:
клуб:
интересы [3]
06-06-2003 11:29 zar » regexps
сижу вот думаю.
требуется добавлять в текст ссылки на ключевые слова. при этом в тексте присутствует html.
пример:
ключевое слово: journals.ru
ссылка: http://journals.ru
на входе:
<i><b>journals</b>.<font color=ffcc00>ru</font></i>
на выходе:
<i><a href=http://journals.ru><b>journals</b>.<font color=ffcc00>ru</font></a></i>

у кого-нибудь есть идеи?
Комментарии:
08-06-2003 00:53
Камрад
регулярные выражения...
08-06-2003 01:01
Камрад
я знаю, из темы сообщения это видно .
а вот как его правильно построить?
08-06-2003 07:35
Камрад
Темная личность
А всегда ли текст на входе соответствует приведённому шаблону? Имеется ввиду порядок тэгов...
08-06-2003 13:50
Камрад
в том то и задача, что набор тэгов произволен. т.е. замена должна происходит вне зависимости от тэгов, их вообще может не быть.

есть идея просто разбить входное слово на буквы и между ними вставить предполагаемые шаблоны тэгов, т.е. динамически сгенерировать регу.
09-06-2003 07:37
Камрад
Темная личность
Я всё-таки не совсем понимаю, что требуется, но не проще ли через str_replace и забить на все тэги? Это "ru" на конце что, так необходимо?
09-06-2003 08:37
Камрад
1. причём тут ru? я просто показал как может быть разбито тэгами ключевое слово. выбери любое другое. набор тэгов был тоже произвольный. пример
<font color=ffcc00>D</font><b>ark</b> при ключевом слове Dark.
2. вся задача в том, что на тэги забить нельзя. не тот случай, где можно упростить.
09-06-2003 09:15
Камрад
несколько кривое решение сделано. криво в плане html, не в той последовательности закрывается последний тэг. но в целом оно работает. также для скорости надо б переписать в ereg_replace.
<?php
  $text = '<font color=ffcc00>D</font><b>ark</b>'; // входной текст
  $key = 'Dark'; // ключевое слово
  $url = 'http://www.journals.ru'; // ссылка
  $template = '(<[^>]+> )*'; // шаблон тэга, поправьте если можно сделать красивее
  $str1 = '';$str2 = '';
  function addslash($c) { // экранируем спец.символы
    $sys = array('.', '*', '+', '?', '(', ')', '[', ']', '{', '}', '^', '$', '\', '|');
    return ((in_array($c, $sys))? '\'.$c:$c);
  }
  for ($i=0;$i<strlen($key);$i++) {  // формируем регу
    $str1 .= ($i==0)? addslash($key[$i]):$template.addslash($key[$i]);
    $str2 .= ($i==0)? $key[$i]:'\'.$i.$key[$i];
  }
  $res = preg_replace(array('!'.$str1.'!Ui'), array('<a href='.$url.'>'.$str2.'</a>'), $text); // реплайсим
  echo $res; // результат.
?>
09-06-2003 12:10
Камрад
В PHP Manual есть такое:

Example 635. Convert HTML to text

// $document should contain an HTML document.
// This will remove HTML tags, javascript sections
// and white space. It will also convert some
// common HTML entities to their text equivalent.

$search = array ("'<script[^>]*?>.*?</script>'si", // Strip out javascript
"'<[\/\!]*?[^<>]*?>'si", // Strip out html tags
"'([\r\n])[\s]+'", // Strip out white space
"'&(quot|#34);'i", // Replace html entities
"'&(amp|#38);'i",
"'&(lt|#60);'i",
"'&(gt|#62);'i",
"'&(nbsp|#160);'i",
"'&(iexcl|#161);'i",
"'&(cent|#162);'i",
"'&(pound|#163);'i",
"'&(copy|#169);'i",
"'&#(\d+);'e"); // evaluate as php

$replace = array ("",
"",
"\\1",
"\"",
"&",
"<",
">",
" ",
chr(161),
chr(162),
chr(163),
chr(169),
"chr(\\1)");

$text = preg_replace ($search, $replace, $document);

А интуиция подсказывает что тут нужен preg_split

Но дальше думать, разумеется, лениво

отредактировано: 09-06-2003 12:13 - cadaver

09-06-2003 14:15
Камрад
to cadaver:
насколько я помню это пример альтернативы strip_tags.
мне же надо оставить html.

насчет моего решения за день пока катался кое-что передумал, позже сяду, сделаю несколько по-другому.
09-06-2003 15:26
Камрад
новый кривой вариант:
<?php
  $text = '<b>journals</b><font color=ffcc00>.</font><u>ru</u>';
  $key = 'journals.ru';
  $url = 'http://journals.ru';

  $template = '([\r\n\t ]*<.*>[\r\n\t ]*)*';
  
  $str1 = ''; $str2 = '';
  function addslash($c) {
    $sys = array('.', '*', '+', '?', '(', ')', '[', ']', '{', '}', '^', '$', '\', '|');
    return ((in_array($c, $sys))? '\'.$c:$c);
  }
  for ($i=0;$i<strlen($key);$i++) {
    $str1 .= $template.addslash($key[$i]);
    $str2 .= '\'.sprintf('%02d', $i+1).$key[$i];
  }
  $str1 .= $template;
  $str2 .= '\'.sprintf('%02d', strlen($key)+1);
  $res = preg_replace(array('!'.$str1.'!Si'), array('<a href='.$url.'>'.$str2.'</a>'), $text);
  echo $res;
?>

кривой впервую очередь тем, что форматирует вслепую. попробуйте предположим подставить в $text такие варианты:
1. <p>какой-то текст и journals.</p><p align=right>runet стал больше и еще там ляля-топаля</p>
2. <table><tr><td>11</td><td>journals</td></tr><tr><td colspan=2>.ru</td></tr></table>
и всё станет ясно
но других решений пока не вижу...
09-06-2003 18:20
Камрад
А, если у тебя все настолько запущено что и такие варианты случаются (а ты бы хоть сказал что делаешь, понятней бы было) то попробуй воспользоваться каким-нибудь HTML-парсером (например этим http://anton.concord.ru/ , PHP HTML Parser v.1.3, This very good instrument allows parse HTML or XML code inside your script. It is very easy to use. If you need in another grammar and rules for the parser, then you can write it without parser's code modifications.)
10-06-2003 07:51
Камрад
да в принципе моего решения мне хватит, единственное сегодня еще наверно приделаю чтобы парсил только внутри заданых тэгов(<p>, <td>, <li> и т.п.).

а делаю я это всё в продолжение темы о wysiwyg-редакторах. пользователь набивает в адм.части форматированный текст, а затем туда требуется автоматом добавлять ссылки...

отредактировано: 10-06-2003 07:54 - zar

11-06-2003 05:38
Камрад
Темная личность
По крайней мере я понял, что требуется.

$text = '<p>какой-то текст и journals.</p><p align=right>runet стал больше и еще там ляля-топаля</p>';
$key = 'journals.ru';
$url = 'http://journals.ru';

for ($i=1; $i<strlen($key); $i++) {
    $str .= '(<.+?> )*'.preg_quote($key[$i]);
}

$str = '/'.preg_quote($key[0]).$str.'/i';

$txt = preg_replace($str, "<a href='".$url."'>\\0</a>", $text);

echo $txt;

отредактировано: 11-06-2003 05:39 - Dark

11-06-2003 07:29
Камрад
to Dark:
аналогично не грамотно вставляет ссылку, между <a..> и </a> оказывается </p><p>.
я думаю правильнее просто ограничить, внутри каких тэгов можно парсить(td, p, li, h* и т.п.).
12-06-2003 07:54
Камрад
Темная личность
Да, про эту ошибку я знаю... Но не всё идеально в этом мире. У меня хотя бы код короче.
Ограничение по тэгам тут - единственный выход. Почему-то в регулярный выражениях исключения можно задавать только символами, но не их последовательностью.
12-06-2003 10:53
Камрад
да, короче . пару велосипедов я на бегу изобрёл.

попозже сяду сделаю окончательный вариант.

с этой сессией нет времени сесть подумать...
Закрыть