3

掲示板からネストされた引用を削除しようとしていますが、いくつか問題があります。

入力例:

[引用著者=personX link=topic=12.msg1910#msg1910 date=1282745641]

[quote author=PersonY link=topic=12.msg1795#msg1795 date=1282727068]

The message in the original quote

[/quote]

最初のメッセージを引用した 2 番目のメッセージ

[/見積もり]

[引用著者=PersonZ リンク=トピック=1.msg1#msg1 日付=1282533805]

ランダムな 3 番目の引用

[/見積もり]

出力例

[引用著者=personX link=topic=12.msg1910#msg1910 date=1282745641]

2番目の引用のメッセージ

[/見積もり]

[引用著者=PersonZ リンク=トピック=1.msg1#msg1 日付=1282533805]

ランダムな 3 番目の引用

[/見積もり]

ご覧のとおり、ネストされた引用 (元のメッセージ) が引用タグとともに削除されます。

私はそれを理解できないようです。

私がしようとすると

$toRemove = '(\\[)(quote)(.*?)(\\])';
$string = $txt;
$found = 0; echo preg_replace("/($toRemove)/e", '$found++ ? \'\' : \'$1\'', $string);

最初のものを除いて、引用タグのすべての出現を削除します。

しかし、コードを次のように展開すると:

$toRemove = '(\\[)(quote)(.*?)(\\])(.*?)(\\[\\/quote\\])';
$string = $txt;
$found = 0; echo preg_replace("/($toRemove)/e", '$found++ ? \'\' : \'$1\'', $string); 

何もしなくなります。

これに関するアイデアはありますか?


編集:

助けてくれてありがとう、ハギ。

私はトラブルに遭遇し続けます。

whileループアラウンド

while ( $input = preg_replace_callback( '~\[quoute.*?\[/quote\]~i', 'replace_callback', $input ) ) {
// replace every occurence
}

ページを無期限にループさせます。削除すると (引用符内の余分な u と共に)、ページは何もしません。

マッチングが原因と判断しました

に変更したとき

$input = preg_replace_callback( '/\[quote(.*?)/i', 'replace_callback', $input );

コードは機能し始めますが、変更すると

$input = preg_replace_callback( '/\[quote(.*?)\[\/quote\]/i', 'replace_callback', $input );

また何もしなくなります。

また、undo_replace 関数には保存されたハッシュが見つからないという問題があり、見つからないインデックスに関する警告のみが表示されます。sha1 に一致する正規表現が正しく機能していないと思います。

私が今持っている完全なコード:

$cache = array();
$input = $txt;

function replace_callback( $matches ) {
    global $cache;
    $hash = sha1( $matches[0] );
    $cache["hash"] = $matches[0];
    return "REPLACE:$hash";
}



// replace all quotes with placeholders
$input = preg_replace_callback( '/\[quote(.*?)\[quote\]/i', 'replace_callback', $input );

function undo_replace( $matches ) {
    global $cache;
    return $cache[$matches[1]];
}

// restore the outer most quotes
$input = preg_replace_callback( '~REPLACE:[a-f0-9]{40}~i', 'undo_replace', $input );

// remove the references to the inner quotes
$input = preg_replace( '~REPLACE:[a-f0-9]{40}~i', '', $input );

echo $input;

アイデアをありがとうございました:)

4

2 に答える 2

2

最初のものだけが残っていることは、非常に簡単にわかります。

'$found++ ? \'\' : \'$1\''

$found を開始すると、未定義で false と評価されるため、$1 が返されます。次に、 $found は 1 ( undefined + 1 = 1 ) にインクリメントされるため、0 より大きくなり、呼び出されるたびにさらにインクリメントされます。ゼロ以外のものはすべて true として評価されるため、その後は常に '' が返されます。

あなたがしたいことは、このようなものです

$cache = array();

function replace_callback( $matches ) {
    global $cache;
    $hash = sha1sum( $matches[0] );
    $cache[$hash] = $matches[0];
    return "REPLACE:$hash";
}

// replace all quotes with placeholders
$count = 0;
do {
    $input = preg_replace_callback( '~\[quoute.*?\[/quote\]~i', 'replace_callback', $input, -1, $count );
    // replace every occurence
} while ($count > 0);

function undo_replace( $matches ) {
    global $cache;
    return $cache[$matches[1]];
}

// restore the outer most quotes
$input = preg_replace_callback( '~REPLACE:[a-f0-9]{40}~i', 'undo_replace', $input );

// remove the references to the inner quotes
$input = preg_replace( '~REPLACE:[a-f0-9]{40}~i', '', $input );

このコードは、PHP を手元に置いてテストしていないため、テストされていません。修正できないエラーがある場合は、ここに投稿してください。修正します。

乾杯、
ハギ

于 2010-08-27T06:53:04.473 に答える
0

ネストされた引用符の preg_replace を使用していくつかのソリューションを検索しましたが、誰も機能しませんでした。だから私は自分の要件に応じて私の小さなバージョンを試しました。

$position = strrpos($string, '[/quote:');  // this will get the position of last quote
$text = substr(strip_tags($string),$position+17); // this will get the data after the last quote used. 

これが誰かを助けることを願っています。

于 2013-08-26T12:39:17.183 に答える