PHP 嵌套正则表达式


PHP nested regex

此字符串:

$subject = ''displaystyle{'ce{Cu^{2+}{(aq)}}+'ce{Zn{(s)}}'ce{->}'ce{Cu_{(s)}}+'ce{Zn^{2+}_{(aq)}}}'

我想捕捉:

  • ''ce{Cu^{2+}{(aq)}}
  • ''ce{Zn{(s)}}
  • ''ce{->}
  • ''ce{Cu_{(s)}}
  • ''ce{Zn^{2+}_{(aq)}}

我的正则表达式受到 PHP 的启发 - 帮助我的基于 REGEX 的递归函数

$pattern = '#''''ce'{(?:[^{}]|(?R))*}#';

我试过

preg_match_all($pattern, $subject, $matches);
print_r($matches);
Array
(
    [0] => Array
        (
            [0] => 'ce{->}
        )
 )

但它不起作用,如您所见...

您可以使用

此递归正则表达式:

(''ce('{(?:[^{}]|(?-1))*'}))

正则表达式演示

在这里(?-1)递归在 ''ce 之后开始的第二个子形态

法典:

$re = "/(
  ''''ce
  (
    ''{
    (?:[^{}]|(?-1))*
    ''}
  )
)/x"; 
$str = 
 "'displaystyle{'ce{Cu^{2+}{(aq)}}+'ce{Zn{(s)}}'ce{->}'ce{Cu_{(s)}}+'ce{Zn^{2+}_{(aq)}}}"; 
if ( preg_match_all($re, $str, $m) )
   print_r($m[1]);

输出:

Array
(
    [0] => 'ce{Cu^{2+}{(aq)}}
    [1] => 'ce{Zn{(s)}}
    [2] => 'ce{->}
    [3] => 'ce{Cu_{(s)}}
    [4] => 'ce{Zn^{2+}_{(aq)}}
)

在我的测试中有效。
请注意,没有平衡大括号'ce不能是子模式。
所以,这将失败'ce{Zn'cepp{(s)}}
而且,这将通过'ce{Zn^{2+}'ce{Zn^{2+}_{(aq)}}_{(aq)}}
否则,为什么要首先寻找'ce{}

 #  '/'''ce('{(?:(?>(?!'''ce)[^{}])+|(?R)|(?1))*'})/'
 ''ce
 (                  # (1 start)
      '{
      (?:
           (?>
                (?! ''ce )         # Not ''ce' ahead
                [^{}]              # A char, but not { or }
           )+
        |                   # or,
           (?R)               # Recurse whole expression
        |                   # or,
           (?1)               # Recurse group 1
      )*
      '}                
 )                  # (1 end)