Xpoint
   [напомнить пароль]

Замена всех [b][/b] на <b></b>

Метки: [без меток]
2006-01-27 12:26:41 [обр] Юрий(0/9)[досье]

Господа, помогите составить регулярное выражение которое будет заменять все [b][/b]
на теги <b></b> во входящем тексте.
У меня получилась следующая комбинация :

$bbcode =~ s/\[([biu]{1})\](.*)\[\/(\1)\]/<$1>$2<\/$3>/gi;

Вроде работало, но потом на некоторых участках текста стало не срабатывать. Либо пол текста выделяет либо не выделяет такую комбинацию. [b]1 день. [Суббота, 13 августа 2005][/b]
Как условие сделать ума не приложу.

спустя 25 минут [обр] Дмитрий Кучкин(3/236)[досье]
$bbcode =~ s/\[([biu])\](.*?)\[\/\1\]/<$1>$2<\/$1>/gi;
спустя 1 минуту [обр] Victor Gr.(0/20)[досье]

А

$bbcode = str_replace ('[b]', '<b>', $bbcode);
$bbcode = str_replace ('[/b]', '</b>', $bbcode);

Чем плохо? Быстрее ведь будет. Если язык - PHP.

спустя 25 минут [обр] Дворнов Роман(3/109)[досье]

Юрий[досье] У Вас проблема с жадностью алгоритма, поможет вопросик после .*
Дмитрий Кучкин[досье] Собственно Вы и решили проблему Юрия, однако

  [b][b][/b][/b]

У вас замениться на

  <b>[b]</b>[/b]

Правильнее и быстрее :)

$bbcode =~ s/\[(\/?[biu])\]/<$1>/gi;

Victor Gr.[досье] Дело не в языке. К тому же у Вас будет два прохода строки, вместо одного.

спустя 4 минуты [обр] Юрий(0/9)[досье]
Во самое оно! Спасибо!
спустя 1 минуту [обр] Алексей В. Иванов(17/2861)[досье]
Юрий[досье] на Вашем примере выражение будет работать, но не для вложенных тэгов, плюс проблема — большая жадность.
Дмитрий Кучкин[досье] не будет работать для вложенных тэгов ([b][i][/i][/b])
Гораздо проще заменять по отдельности, как сказал Victor Gr.[досье], но можно воспользоваться более медленным вариантом: while ($bbcode =~ s#\[([biu])\](.*?)\[/\1\]#<$1>$2<\/$1>#gio) {};
спустя 3 минуты [обр] Алексей В. Иванов(17/2861)[досье]
Единственный минус такого варианта: $bbcode =~ s/\[(\/?[biu])\]/<$1>/gi; это то, что если человек ошибется парностью [b], то это может "вылезти наружу" и окрасить всю страницу. В случае с выражением, которое учитывает парность "кривые" [b] так и останутся в квадратных скобках.
спустя 9 часов [обр] Дворнов Роман(3/109)[досье]

Если Вам и корректность закрытия нужна, то

$tags = {};
$bbcode =~ s/\[(\/?)([biu])\]/
             if ($1) 
             { pop @{$tags->{$2}}; "<\/" . $2 . ">" }
             else
             { push @{$tags->{$2}}, 1; "<" . $2 . ">" }
            /gei;
for my $key (keys %$tags)
{
  while (@{$tags->{$key}})
  {
     pop @{$tags->{$key}};
    $bbcode .= "</" . $key . ">";
  }
}
print $bbcode;

не закрытых тегов быть не должно :)

Powered by POEM™ Engine Copyright © 2002-2005