>我有一个初始字符串,其中的标签之间有杂项文本,并且字符串可以包含嵌套标记。 我希望根据以下规则"取消嵌套"字符串:1) 最终字符串与初始标签没有区别,除了添加或删除一些标签。2)在最后一个字符串中,每条文本都用最近的一对括起来将其包含在原始字符串中的标记。如果有几个相等的近对,未指定(但 3)中的结果是没有一段文本在最终字符串中归属新标签)。
因此
[a]text1[/a]text2[b]text3[c]text4[/c]text5[/b]
[e]text6[f]text7[/e]text8[/f]
应该成为
[a]text1[/a]text2[b]text3[/b][c]text4[/c][b]text5[/b]
[e]text6[/e]...[f]text8[/f]
其中…
可能是text7
、[e]text7[/e]
或[f]text7[/f]
中的任何一个。
是否有一个正则表达式(例如,PHP 中的递归 PCRE 正则表达式)可以做到这一点?
方法
执行 3 次替换:
-
搜索一个结束标签,后跟另一个结束标签 ==>为第二个插入一个开始标签。例:
[/b]text[/c] ==> [/b][c]text[/c]
-
搜索一个开始标签,后跟一个标签,该标签不是与刚刚找到的标签对应的结束标签 ==>插入结束标签。例:
[a]text[b] ==> [a]text[/a][b] [a]text[/b] ==> [a]text[/a][/b]
-
(修复 2)。搜索 2 个连续的结束标签 ==>删除第二个。例:
[a]text[/a][/b] ==> [a]text[/a]
法典
$patterns = array ('#('[/'w++])([^[]++'[/('w++)])#',
'#'[('w++)][^[]*+(?!'[/'1)#',
'#('[/('w++)])'[/'w++]#');
$replace = array (''1['3]'2',
''0[/'1]',
''1');
$string = "[a]text1[/a]text2[b]text3[c]text4[/c]text5[/b]'n[e]text6[f]text7[/e]text8[/f]";
$result = preg_replace($patterns, $replace, $string);
输出
[a]text1[/a]text2[b]text3[/b][c]text4[/c][b]text5[/b]
[e]text6[/e][f]text7[/f][f]text8[/f]
- 测试它