【问题标题】:Regex to isolate trailing nested quote tags正则表达式隔离尾随嵌套引号标签
【发布时间】:2018-01-12 23:21:43
【问题描述】:

我正在使用一些多年来升级的旧 PHP 论坛软件,但在此过程中,有些帖子在帖子底部包含单选 [QUOTE] 块。

我正在尝试找出一种方法来运行 PHP preg_replace 以将它们正则表达式。我只想删除出现在帖子内容下方的 QUOTE 标签(也可能包含嵌套的引号标签)。

例如,保留原样的帖子可能如下所示:

Here is the example post text

[QUOTE]
This is an appropriate quote
[/QUOTE]

Here is more post content

在如下所示的帖子中,我想尝试删除最后一个引用块:

Here is the example post text

[QUOTE]
This is an appropriate quote
[/QUOTE]

Here is more post content

[QUOTE]
This is an unnecessary quote, as it's below all of the post text
   [QUOTE]
   Here's an unnecessary nested quote, just to confuse things.
   [/QUOTE]
[/QUOTE]

我花了几个小时试图想出一个正则表达式来捕获最后一种类型的引用块,但无济于事。我知道我需要以以下内容结尾,因为结尾引号将始终在帖子末尾带有此标签:

\[\/QUOTE\]$

有没有办法可以在正则表达式中捕获整个最终 QUOTE 块,包括任何可能的嵌套引号?到目前为止,我尝试过的任何内容都会尝试匹配嵌套的开始引号标记以及最终结束标记(而不是匹配对)。

【问题讨论】:

    标签: php regex preg-replace


    【解决方案1】:

    您可能希望使用递归但锚定方法:

    (\[QUOTE[^][]*\]
    (?:[^][]++|(?1))++
    \[/QUOTE\])
    \Z
    

    a demo on regex101.com。这里只匹配最后的引用块(\Z)。

    【讨论】:

    • 太棒了 - 这很简单,似乎适用于我迄今为止测试过的所有案例!谢谢你:)。
    • 我已经在论坛上推出了这个,效果很好!我有一个类似的问题here,我想知道这个正则表达式是否也可以修改以适应它?
    • @user2874582:是的,在stackoverflow.com/questions/48284022/…提供了一个有效的答案
    【解决方案2】:

    您可以像这样匹配字符串末尾的嵌套 bb 代码。

    (?is)\[quote\]((?&core)|)\[/quote\]$(?(DEFINE)(?<core>(?>(?&content)|\[quote\](?:(?&core)|)\[/quote\])+)(?<content>(?>(?!\[/?quote\]).)+))

    演示:https://regex101.com/r/uFPyXX/2

     (?is)
    
     \[quote\]                          # Start-Delimiter
     (                                  # (1), The CORE
          (?&core) 
       |  
     )
     \[/quote\]                         # End-Delimiter
    
     $                                  # End of string
    
     # ///////////////////////
     # // Subroutines
     # // ---------------
    
     (?(DEFINE)
    
          # core
          (?<core>
               (?>
                    (?&content) 
                 |  
                    \[quote\]
                    # recurse core
                    (?:
                         (?&core)                           # Core
                      |                                   # or, nothing
                    )
                    \[/quote\]
               )+
          )
    
          # content 
          (?<content>
               (?>
                    (?!
                         \[/?quote\]
                    )
                    . 
               )+
          )
    
     )
    

    请注意,如果您需要限定现有报价在此之前
    告诉我,我会给你一个模组。

    【讨论】: