2014-11-21 140 views
0

我使用正則表達式,但我不能做我的情況。我已經創建了像DLE一樣的引擎。 我有一個像[A],[/ A],[B] [/ B]等我用正則表達式的標籤像正則表達式:嵌套標籤

'\\[a\\](.*?)\\[/a\\]'si 

或類似

'\\[a\\](.*?)(\\[/a\\])+'si 

,它不工作我想如何。 我需要接收:

from '[a]delete[/a]' : '' 

from '[a][b]delete[/b][/a]' : '', 

from '[a][a]delete[/a][/a]' : '', with '\\[a\\](.*?)\\[/a\\]'si it returns '[/a]' 

from '[b][a]delete[/a][b]' : '[b][/b]' 

from '[b][a]delete[/a][b] [a]delete[/a]' : '[b][/b]' 

from '[a] 
      delete 
      [a] 
       [b]delete[/b] 
      [/a] 
      delete 
     [/a] 
     [b] 
      [a]delete[/a] 
      nodelete 
     [/b]' 
     : 
     '[b] 
      nodelete 
     [/b]' 

幫助我創建正確的正則表達式!

+0

該語法看起來接近於HTML。並且請注意,[HTML不能用正則表達式解析](http://stackoverflow.com/a/1732454/1529630)。也許這也適用於你的語法。 – Oriol 2014-11-21 15:42:00

+0

您的輸入是什麼?或者您的信息是在您的信息中輸入的?如果是這樣,你的預期產出是多少? 正如@Oriol指出的,你不能用RegEx解析HTML(和類似的結構),你可能需要一個遞歸函數,它可以使用RegEx – 2014-11-21 15:43:38

+0

我可以爲我的任務編寫自己的函數。但我想知道:我可以在這個任務中使用正則表達式嗎? – tesst 2014-11-21 15:44:01

回答

2

PHP方式

您可以一次用PHP做。但對付嵌套的標籤,你需要使用遞歸功能,所以你不能做同樣的用javascript:

$text = preg_replace('~\s*\[a](?:[^[]+|\[(?!/?a])|(?R))*+\[/a]\s*~', '', $text); 

online demo

圖案的詳細資料

~     # pattern delimiter 
\s*    # only here to remove leading whitespaces 
\[a] 
(?:    # non-capturing group: describes the allowed 
        # content between tags: 
    [^[]+   # - all that is not a [ 
    |    # OR 
    \[ (?!/?a]) # - a [ that is not the begining of an opening 
        #  or closing "a" tag 
    |    # OR 
    (?R)   # - recurse to the whole pattern 
)*+    # repeat the group zero or more times (possessive quantifier) 
\[/a] 
\s*    # to remove trailing spaces 
~ 

Javascript方式

由於遞歸功能不是可用於ECMAScript正則表達式引擎,解決該問題的一種方法是使用幾次以最內層的「a」標籤爲目標的替換通路。爲了完成這個任務,你可以使用這個模式,禁止嵌套「一」的標籤(注意,模式非常類似於以前,語法(?=(subpattern*))\1只模仿佔有慾量詞)

text = text.replace(/\s*\[a\](?=((?:[^\[]+|\[(?!\/?a\]))*))\1\[\/a\]\s*/g, ''); 

您需要應用此替換,直到沒有更多標籤要替換。您可以使用閉包檢測替換次數,以增加計數器的替換次數,然後將所有替換置於do...while循環中。示例:

var counter;  
do { 
    counter = 0; 
    text = text.replace(/\s*\[a\](?=((?:[^\[]+|\[(?!\/?a\]))*))\1\[\/a\]\s*/g, function (m) {counter++; return '';}); 
} while (counter>0) 
+0

大大的感謝! – tesst 2014-11-21 17:08:41