5

PHP で作成された Web サイトで、自分の個人的なフォーラム用に 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);

これは、引用が1つの場合に機能しますが、ユーザーが引用を引用すると、これは機能しません。したがって、この動作を適用するには、一種の再帰的な引用が必要です。

非常に多くのトピックを検索しようとしましたが、どのように機能するのかよくわかりません。この種の操作を行うための提案/ヒントをいただければ幸いです。教えてください、ありがとう!

編集

最後に、これは私自身の解決策です:

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 の破損やその他の悪意のある攻撃を防ぐ必要があります (そうですか?)。どう思いますか?

4

3 に答える 3

4

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-それ自体を呼び出します。

于 2011-05-08T15:33:26.187 に答える
1

開始引用符タグを開始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);
}
?>
于 2011-05-08T15:37:28.510 に答える
0

このような再帰構文は、まさに正規表現が弱すぎるときです。代わりに、ある種のパーサーの使用を検討する必要があります。

正規表現 (少なくとも一部の拡張子なし) は、通常の言語のみを受け入れることができます。再帰構文を使用するには、文脈自由言語が必要です。これらには、より洗練されたパーサーが必要です。

于 2011-05-08T15:24:04.610 に答える