代码之家  ›  专栏  ›  技术社区  ›  IanCun

嵌套引号内的子模式Regex匹配

  •  1
  • IanCun  · 技术社区  · 7 年前

    我正在从一些旧的论坛软件升级,其中有许多不必要的嵌套[引用]标签,我想通过Regex(使用PHP preg\u replace)去掉这些标签。其中大部分已经完成,但我正在努力解决以下类型的问题。

    帖子中有嵌套的引号块,但只需要保留顶层[引号]内容(因为一些嵌套引号有3或4层深)。

    例如:

    Here is some normal post content
    
    [QUOTE]
    This is an appropriate quote
    [/QUOTE]
    
    Here is more post content
    
    [QUOTE]
    This is a a valid quote, as it's only 1 level deep.
       [QUOTE="User 2"]
       Here's an unnecessary nested quote.
           [QUOTE]
           Here's a 3nd level unnecessary nested quote.
           [/QUOTE]
       [/QUOTE]
    [/QUOTE]
    
    Here is more post content
    

    我想去掉第二级和第三级嵌套引号,但不知道如何去掉。

    我有一些很好的建议 strip nested quotes 完全正确,但我无法修改regex模式以适应此示例。

    2 回复  |  直到 7 年前
        1
  •  2
  •   Sebastian Proske    7 年前

    使用与链接的regex相同的限制(引号内没有其他标记),您可以使用

    ((?:\[QUOTE\]|\G(?!^))[^][]+)((\[QUOTE[^][]*\](?:[^][]++|(?2))++\[/QUOTE\])) 
    

    搜索,然后 $1 仅替换嵌套引号。

    这基本上匹配了单独组中最外面的引号,并且只匹配递归中的内部引号,因此只允许删除它们。

    看见 https://regex101.com/r/y39Xaf/2

    我添加了一个测试用例,在一个外部引用中包含两个不同的引用。

    一个小故障 ((?:\[QUOTE\]|\G(?!^))[^][]+) :

    • 所有内容都包含在捕获组中,以允许重新插入
    • (?:\[QUOTE\]|\G(?!^) 匹配任一文字 [QUOTE] 或上一场比赛结束时
    • [^][]+ 匹配任何普通文本
        2
  •  1
  •   Jan    7 年前

    是的,您可以使用链接答案中的相同正则表达式并应用它 两次 结合一些编程逻辑:

    <?php
    
    $regex = '~
            (\[QUOTE[^][]*\]
            (?:[^][]++|(?1))++
            \[/QUOTE\])
            ~x';
    
    $data = preg_replace_callback($regex, 
        function($match) use($regex) {
            return $match[0][0] . preg_replace($regex, '', substr($match[0], 1));
        },
        $your_data_string_here);
    
    echo $data;
    ?>
    


    这为您的示例提供了:
    Here is some normal post content
    
    [QUOTE]
    This is an appropriate quote
    [/QUOTE]
    
    Here is more post content
    
    [QUOTE]
    This is a a valid quote, as it's only 1 level deep.
    
    [/QUOTE]
    
    Here is more post content
    


    这里的想法是匹配每个引号标记(嵌套或非嵌套),然后将相同的表达式应用于匹配的字符串,但偏移量为+1。当我们获取一个子字符串时,只有下一个嵌套的 [QUOTE] 找到并替换。

    A. demo on regex101.com on ideone.com 进一步澄清了这一点。