2010-08-27 22 views
3

我試圖從我的公告板上刪除嵌套引用,但我遇到了一些問題。在PHP中刪除嵌套的bbcode(引號)

示例輸入:

[報價作者= personX鏈接=主題= 12.msg1910#msg1910日期= 1282745641]

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

The message in the original quote 

[/quote] 

甲第二消息引用的第一個

[/ quote]

[quote author = PersonZ link = topic = 1.msg1#msg1 da TE = 1282533805]

隨機第三報價

[/報價]

實施例輸出

[報價作者= personX鏈接=主題= 12.msg1910#msg1910 date = 1282745641]

消息在第二個報價

[/報價]

[報價作者= PersonZ鏈接=主題= 1.msg1#MSG1日期= 1282533805]

隨機第三報價

[/報價]

正如您所看到的嵌套報價(原始消息)與報價標籤一起被刪除。

我似乎無法弄清楚。

當我嘗試

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

它停止這樣做什麼都沒有。

對此的任何想法?


編輯:

感謝您的幫助,Haggi。

不過,Ik一直在跑。

各地

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

while循環導致頁面無限循環,取出時(在quoute額外ü沿)時,頁面沒有做任何事情。

我已經確定,原因是匹配

時改爲

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

代碼沒有開始工作,但當改爲

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

它stopts再次做任何事情。

另外,還有一個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; 

再次感謝您的任何想法傢伙:)

+0

請替換$ cache [「hash」] = $ matches [0];由$ cache [$ hash] = $ matches [0]; – haggi 2010-08-27 18:16:10

+0

修復了循環中的錯誤。請在我編輯的文章中嘗試新版本 – haggi 2010-08-27 18:19:24

回答

2

的第一個是留是很容易發現的只有一個:

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

當啓動$ found時未定義並且計算結果爲false,因此返回$ 1。然後$ found會增加到1(undefined + 1 = 1),所以它大於零,每次調用它都會進一步遞增。因爲所有與零不同的東西在此之後都被評估爲真,所以你總是得到''回來。

你想要做的就是這樣的事情

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

此代碼是未經測試的,因爲我不HABE PHP在手邊,以便測試它。如果有任何錯誤無法修復,請將它們張貼在這裏,我會修復它們。

乾杯,
haggi

+0

haggi還存在一些問題,但是感謝您的幫助。我用我的發現編輯了原文。 – Kevin 2010-08-27 13:39:54

0

我搜索與preg_replace函數嵌套報價夫婦的解決方案,但沒有一個奏效。所以我根據我的要求嘗試了我的littel版本。

$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. 

希望這會幫助別人。