我使用正则表达式,但我无法为我的情况做这件事。我已经创建了像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 :(得分:2)
PHP方式
你可以用php一次性完成。但是要处理嵌套标签,你需要使用递归功能,所以你不能用Javascript做同样的事情:
$text = preg_replace('~\s*\[a](?:[^[]+|\[(?!/?a])|(?R))*+\[/a]\s*~', '', $text);
模式详情
~ # 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"标签。要完成此任务,您可以使用此模式禁止嵌套" 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)