PHP 嵌套正则表达式
PHP nested regex
这个字符串:
$subject = '\displaystyle{\ce{Cu^{2+}{(aq)}}+\ce{Zn{(s)}}\ce{->}\ce{Cu_{(s)}}+\ce{Zn^{2+}_{(aq)}}}'
我要捕捉:
- \ce{铜^{2+}{(aq)}}
- \ce{Zn{(s)}}
- \ce{->}
- \ce{Cu_{(s)}}
- \ce{Zn^{2+}_{(aq)}}
我的正则表达式灵感来自 PHP - help with my REGEX-based recursive function
$pattern = '#\\ce\{(?:[^{}]|(?R))*}#';
我试过
preg_match_all($pattern, $subject, $matches);
print_r($matches);
Array
(
[0] => Array
(
[0] => \ce{->}
)
)
但如您所见,它不起作用...
您可以使用这个递归正则表达式:
(\ce(\{(?:[^{}]|(?-1))*\}))
RegEx Demo
这里 (?-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)
这个字符串:
$subject = '\displaystyle{\ce{Cu^{2+}{(aq)}}+\ce{Zn{(s)}}\ce{->}\ce{Cu_{(s)}}+\ce{Zn^{2+}_{(aq)}}}'
我要捕捉:
- \ce{铜^{2+}{(aq)}}
- \ce{Zn{(s)}}
- \ce{->}
- \ce{Cu_{(s)}}
- \ce{Zn^{2+}_{(aq)}}
我的正则表达式灵感来自 PHP - help with my REGEX-based recursive function
$pattern = '#\\ce\{(?:[^{}]|(?R))*}#';
我试过
preg_match_all($pattern, $subject, $matches);
print_r($matches);
Array
(
[0] => Array
(
[0] => \ce{->}
)
)
但如您所见,它不起作用...
您可以使用这个递归正则表达式:
(\ce(\{(?:[^{}]|(?-1))*\}))
RegEx Demo
这里 (?-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)