Рекурсивная цитата на форуме - PullRequest
5 голосов
/ 08 мая 2011

Я написал функцию Quote для своего личного форума на веб-сайте, написанном на PHP.

Теги сообщения в кавычках выглядят как [quote=username]message[/quote], поэтому я написал эту функцию:

$str=preg_replace('#\[quote=(.*?)\](.*?)\[/quote\]#is', '<div class="messageQuoted"><i><a href="index.php?explore=userview&userv=$1">$1</a> wrote :</i>$2</div>', $str);

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

Я пытался искать по ТАКому количеству тем, но я не совсем понимаю, как это может работать. Буду признателен за любые предложения / советы по выполнению такого рода операций! Дайте мне знать, и спасибо!

РЕДАКТИРОВАТЬ

В конце концов, это мое собственное решение:

if(preg_match_all('#\[quote=(.*?)\](.*?)#is', $str, $matches)==preg_match_all('#\[/quote\]#is', $str, $matches)) {
    array_push($format_search, '#\[quote=(.*?)\](.*?)#is');
    array_push($format_search, '#\[/quote\]#is');

    array_push($format_replace, '<div class="messageQuoted"><a class="lblackb" href="index.php?explore=userview&userv=$1">$1</a> wrote :<br />$2');
    array_push($format_replace, '</div>');
}

$str=preg_replace($format_search, $format_replace, $str);

он заменяет только если число совпадений правильное. Так что следует (верно?) Предотвращать html-атаки или другие злонамеренные атаки. Что ты думаешь?

Ответы [ 3 ]

4 голосов
/ 08 мая 2011

PCRE и регулярные выражения в PHP допускают рекурсию http://php.net/manual/en/regexp.reference.recursive.php - для этого вам потребуется синтаксис (?R).

Но обычно он совпадает только рекурсивно, он не применяет вашу строку заменырекурсивно.Поэтому вам нужно как минимум использовать preg_replace_callback.

Трудно приступить к работе, но я верю (совершенно не проверено), что это может сделать в вашем случае:

= preg_replace_callback('#\[quote=(.*?)\]((?:(?R)|.*?)+)\[/quote\]#is',
          'cb_bbcode_quote', $str);

Теперьcallback возвращает обернутый контент, после того как ему снова придется вызывать то же регулярное выражение для внутреннего текста $ match [1], и сам preg_replace_callback-call.

1 голос
/ 08 мая 2011

Вы можете просто заменить открывающий тег цитаты на открывающий тег div и то же самое для закрывающего раздела.Это только плохо, если пользователь испортил его соответствие тега кавычки.В качестве альтернативы вы можете использовать функцию цитаты из внутреннего раздела:

<?php
function quote($str)
{
    if( preg_match('#\[quote=.*?\](.*)\[/quote\]#i', $str) )
         return quote(preg_replace('#\[quote=.*?\](.*)\[/quote\]#i', '$1', $str);
    return preg_replace('#\[quote=.*?\](.*)\[/quote\]#', '<div blabla>$1</div>', $str);
}
?>
0 голосов
/ 08 мая 2011

Рекурсивный синтаксис, подобный этому, именно тогда, когда регулярные выражения становятся слишком слабыми. Вместо этого вы должны использовать какой-то парсер.

Регулярные выражения (по крайней мере, без некоторых расширений), могут принимать только регулярные языки . Чтобы иметь рекурсивный синтаксис, вам нужен контекстно-свободный язык . Это требует более сложных парсеров.

...