2014-11-21 84 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