正则表达式隔离尾随嵌套的引用标记

时间:2018-01-12 23:21:44

标签: php regex preg-replace

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

我正在试图找出一种方法来运行PHP preg_replace到Regex它们。我只想删除帖子内容下面出现的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块,包括任何可能的嵌套引号?到目前为止我尝试过的任何东西都会尝试匹配嵌套的开始引号,以及最终的结束标记(而不是匹配的对)。

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

您可以像这样匹配字符串末尾的嵌套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\]
                )
                . 
           )+
      )

 )

请注意,如果您需要在此之前确定现有报价 让我知道,我会给你一个mod。