论坛中的递归引用

发布于 2024-11-06 06:33:44 字数 1143 浏览 3 评论 0原文

我在一个用 PHP 编写的网站中为我自己的个人论坛编写了一个 Quote 函数。

消息引用标签看起来像 [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 损坏或其他恶意攻击。你怎么认为?

I have wrote a Quote function for my own personal forum, in a website written with PHP.

The message quoted tags looks like [quote=username]message[/quote], so I wrote that function :

$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);

This one works if the quote is one, but then a user quote a quote, this doesnt works. So I need a sort of recursive quote for apply this behaviour.

I tried to searching on SO many topics, but I don't really understand how it can works.
Would be appreciated any suggestions/tips for do this kind of operation! Let me know, and thanks!

EDIT

At the end, this is my own solution :

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);

it repleace only if the number of occurences is correct. So it should (right?) to prevent html broke or other malicious attack. What do you think?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我为君王 2024-11-13 06:33:44

PHP 中的 PCRE 和正则表达式允许递归 http://php.net/manual/ en/regexp.reference.recursive.php - 您将需要 (?R) 语法。

但它通常只递归匹配,它不会递归应用您的替换字符串。因此,为什么您至少需要使用 preg_replace_callback

很难开始工作,但我相信(完全未经测试)这可能适合您的情况:

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

现在回调返回包装的内容,之后它必须在 $match[1] 内部文本上再次调用相同的正则表达式,并且 preg_replace_callback-调用它自己。

PCRE and regexes in PHP do allow for recursion http://php.net/manual/en/regexp.reference.recursive.php - You will need the (?R) syntax for that.

But it usually only matches recursively, it does not apply your replacement string recursively. Hencewhy you need to use preg_replace_callback at the very least.

It's difficult to get working, but I believe (totally untested) this might do in your case:

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

Now the callback returns the wrapped content, after it has to invoke the same regex again on the $match[1] inner text, and preg_replace_callback-call itself.

裂开嘴轻声笑有多痛 2024-11-13 06:33:44

您只需将开始引号标记替换为开始 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);
}
?>

You can simply replace the opening quote tag with the opening div tag and same for the closing section. This only goes bad if the user messes up it's quote tag matching.
Alternatively you can recurse the quote function with the inner section:

<?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);
}
?>
冷月断魂刀 2024-11-13 06:33:44

像这样的递归语法正是正则表达式开始变得太弱的时候。您应该考虑使用某种解析器。

正则表达式(至少没有某些扩展)只能接受常规语言。为了使用递归语法,您需要一种上下文无关语言。这些需要更复杂的解析器。

Recursive syntax like this is precisely when regular expressions start being too weak. You should look into using some kind of parser instead.

Regular expressions (at least without some extensions), can only accept regular languages. In order to have a recursive syntax, you need a context-free language. These require more sophisticated parsers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文