PHP 中是否有(递归)PCRE 正则表达式来拒绝标记


Is there a (recursive) PCRE regexp in PHP to denest tags

>我有一个初始字符串,其中的标签之间有杂项文本,并且字符串可以包含嵌套标记。 我希望根据以下规则"取消嵌套"字符串: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 次替换:

  1. 搜索一个结束标签,后跟另一个结束标签 ==>为第二个插入一个开始标签。例:

    [/b]text[/c]      ==>   [/b][c]text[/c]
    
  2. 搜索一个开始标签,后跟一个标签,该标签不是与刚刚找到的标签对应的结束标签 ==>插入结束标签。例:

    [a]text[b]        ==>   [a]text[/a][b]
    [a]text[/b]       ==>   [a]text[/a][/b]
    
  3. (修复 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]
  • 测试它