我正在尝试使用Casimir et Hippolyte的模式(这里)将HTML标签包装在字符串中。
$html = <<<EOD
$str
EOD;
$pattern = <<<'EOD'
~
(?(DEFINE)
(?<self> < [^'W_]++ [^>]* > )
(?<comment> <!-- (?>[^-]++|-(?!->))* -->)
(?<cdata> 'Q<![CDATA['E (?>[^]]++|](?!]>))* ]]> )
(?<text> [^<]++ )
(?<tag>
< ([^'W_]++) [^>]* >
(?> 'g<text> | 'g<tag> | 'g<self> | 'g<comment> | 'g<cdata> )*
</ 'g{-1} >
)
)
# main pattern
(?: 'g<tag> | 'g<self> | 'g<comment> | 'g<cdata> )+
~x
EOD;
实现此方法后,我收到一个错误Compilation failed: assertion expected after (?( at offset 6
.这种模式有什么问题?
经过一些研究,PCRE 版本 <7.2 似乎在 DEFINE 语法中存在这种错误。
您可以像这样编写相同的模式:
$pattern = <<<'EOD'
~
(?:
(?<tag>
< ([^'W_]++) [^>]* >
(?> (?<text> [^<]++ )
| 'g<tag>
| (?<self> < [^'W_]++ [^>]* > )
| (?<comment> <!-- (?>[^-]++|-(?!->))* -->)
| (?<cdata> 'Q<![CDATA['E (?>[^]]++|](?!]>))* ]]>)
)*
</ 'g{2} > # second group from pattern start (<tag> is 1st)
)
| 'g<self> | 'g<comment> | 'g<cdata>
)+
~x
EOD;