2012-08-10 38 views
0

你好嗎?我會直指點。PHP preg_replace崩潰。僅適用於正則表達式大師

我使用遞歸正則表達式基本上去除個體或嵌套< BLOCKQUOTE>標記。我只需要刪除純文本,嵌套或不嵌套,並留下任何超出這些的文字。

此正則表達式不正是我想要的工作(注意,使用先行和遞歸)

$comment=preg_replace('#<blockquote>((?!(</?blockquote>)).|(?R))*</blockquote>#s',"",$comment); 

,但它有一個很大的問題:當$評論是大(超過3500個字符) ,Apache崩潰(我假設分段錯誤)。

我需要一個解決問題的辦法,要麼但解決崩潰,使用更好的正則表達式自定義函數,將做的工作也是如此。

如果您只是想知道如何去除嵌套的特定標籤,歡迎他們。

謝謝你提前

+3

請不要使用正則表達式解析HTML,因爲它會[驅動你į̷̷͚̤̤̖̦͍͗̒̈̅̄n̨͖͓̹͍͎͔͈̝͐ͪ͛̄͛ṣ̷̵̞̦ͤ̅̉̋ͪ͑͛ͥ͜a̷̘͖̮͔͎͛̇̏̒͆̆͘n͇͔̤̼͙̩͖̭ͤ͋̉͌͟eͥ͒͆ͧͨ̽͞҉̹͍̳̻͢](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454 #1732454)。改爲使用[HTML解析器](http://stackoverflow.com/questions/292926/robust-mature-html-parser-for-php)。 – 2012-08-10 23:29:07

+0

Segfault = [堆棧溢出](http://en.wikipedia.org/wiki/Stack_overflow)=可能是無限遞歸。你確定它只是字符串的大小,還是它導致問題的內容?儘管@Truth講述了*真相*(哈!) - HTML解析器對於這項工作來說是一個更好的工具。如果你必須堅持使用正則表達式,並且你確定表達式符合你的需求,那就試着在它上面放一個「S」(研究)標誌,我已經看到它修復了許多罪惡。 – DaveRandom 2012-08-11 00:00:11

+0

@Truth恭喜,你似乎已經找到了一種方式來打破SO CSS的評論。 Skillz ... – DaveRandom 2012-08-11 00:01:49

回答

1

男人,你的模式sigfaults像瘋了!甚至幾百字節的評論以崩潰結束。

使用preg_split()來分割字符串很簡單,然後使用計數器來跟蹤您的深度。當深度大於1時,你會丟棄文本。這裏的實現:

$tokens = preg_split('#(</?blockquote.*?>)#s', $comment, -1, PREG_SPLIT_DELIM_CAPTURE); 
$outsideTokens = array(); 
$depth = 0; 
for($token = reset($tokens); $token !== false; $token = next($tokens)) { 
    if($depth == 0) { 
     $outsideTokens[] = $token; 
    } 
    $delimiter = next($tokens); 
    if($delimiter[1] == '/') { 
     $depth--; 
    } else { 
     $depth++; 
    } 
} 
$comment = implode($outsideTokens); 

即使開始標籤包含屬性,代碼也應該工作。

+0

哇!你剛剛做到了。我無法弄清楚,你只是做到了!恭喜,很多謝謝! – Dandy 2012-08-11 02:00:35