困难 PHP 嵌套正则表达式

Difficult PHP Nested Regular Expression

给定以下字符串:

{start} SubPattern1 {end} 
....
{start} SubPattern2 {end}
....
{start} {start}SubPattern3{end} {end}

我需要找到给出以下结果的正则表达式:

preg_match_all($regex, $string, $result);

print_r($result);

array(2
    0 => array(3
        0 => {start} SubPattern1 {end}
        1 => {start} SubPattern2 {end}
        2 => {start} {start}SubPattern3{end} {end}
    )
    1 => array(3
        0 => SubPattern1 
        1 => SubPattern2 
        2 => {start}SubPattern3{end} 
    )
)

谢谢!

编辑

出于视觉目的,我写了一个多行字符串。但我需要即使所有文本都在一行字符串中,表达式也能正常工作。例如:

{start}SubPattern1{end}{start}SubPattern2{end}{start}{start}SubPattern3{end}{end}

你可以用这个

^{start}(.*){end}$
  • ^ - 字符串开始。
  • {start} - 匹配 {start}.
  • (.*) - 匹配除新行之外的任何内容。 (捕获组)。
  • {end} - 匹配 {end}.
  • $ - 字符串结束。

Demo

您可以匹配 {start} 和 {end} 并使用捕获组并对模式使用递归:

{start}((?:(?:(?!{(?:start|end)}).)+|(?R))*){end}

例如:

$string = <<<DATA
{start} SubPattern1 {end} 
{start} SubPattern2 {end}
{start} {start}SubPattern3{end} {end}
DATA;

preg_match_all('/{start}((?:(?:(?!{(?:start|end)}).)+|(?R))*){end}/', $string, $result);
print_r($result);

说明

  • {start}字面匹配
  • (开始抓包
    • (?:非捕获组
      • (?:非捕获组
        • (?!{(?:start|end)}). 断言右侧内容不是 {start} 或 {end} 的否定前瞻。如果是这样,则匹配任何字符。
      • )+|(?R) 关闭非捕获组并重复 1+ 次或 | 递归整个模式
    • )*关闭非捕获组并重复0+次
  • ) 关闭捕获组
  • {end} - 字面匹配

Regex demo

结果:

Array
(
    [0] => Array
        (
            [0] => {start} SubPattern1 {end}
            [1] => {start} SubPattern2 {end}
            [2] => {start} {start}SubPattern3{end} {end}
        )

    [1] => Array
        (
            [0] =>  SubPattern1 
            [1] =>  SubPattern2 
            [2] =>  {start}SubPattern3{end} 
        )

)

Php demo