递归地抓取嵌套匹配字符之间的所有文本

时间:2017-11-30 02:44:05

标签: php regex preg-match-all

这是一个示例输入字符串:

((#1662# - #[Réz-de-chaussée][Thermostate][Temperature Actuel]#) > 4) && #1304# == 1 and #[Aucun][Template][ReviseConfort#templateSuffix#]#

这些是必需的输出字符串:

#1662#
#[Réz-de-chaussée][Thermostate][Temperature Actuel]#
#1304#
#[Aucun][Template][ReviseConfort#templateSuffix#]#

我试过这个正则表达式,但它不起作用:

~("|\').*?\1(*SKIP)(*FAIL)|\#(?:[^##]|(?R))*\#~

3 个答案:

答案 0 :(得分:0)

preg_match_all( '/\#((\d{1,4})|(\[[^0-9]+\]))[\#$]/'
              , '((#1662# - #[Réz-de-chaussée][Thermostate][Temperature Actuel]$) > 4) && #1304$ == 1 and #[Aucun][Template][ReviseConfort#templateSuffix#]#'
              , $matches
              );
foreach($matches[0] as $match)
    echo $match.PHP_EOL;

答案 1 :(得分:0)

试试这个(?:#[^#[]+#|##(?:.+?]#){2}|#(?:.+?]#){1})

说明:

(?:
// Grabs everything between 1 opening # and 1 closing # tag that`s not #[ chars
   #[^#[]+#|
// Grabs everything between 2 opening # and 2 closing ]# tags
   ##(?:.+?]#){2}|
// Grabs everything between 1 opening # and 1 closing ]# tag
   #(?:.+?]#){1}
)

答案 2 :(得分:0)

这种情况并不特别适合递归。使用普通的正则表达式会更好。

很难确定以下内容是否适用于所有其他可能的输入,因为您只提供了两个有限的示例。

至少在这些示例中,所需的结束#之后是),空格或行尾。对这些值使用负前瞻允许我们捕获内部嵌套的#

#(?:[^#]|#(?![\s)]|$))+#

Demo