最初にティムが正しく指摘したように、HTMLを正規表現で解析するのは賢明ではありません。
2 番目: 提示されているように、質問の正規表現は読み取り不能です。私はそれを再フォーマットする自由を取りました。これは、まったく同じ正規表現のコメント付きの読み取り可能なバージョンを含む作業スクリプトです。
<?php // test.php Rev:20120830_1300
$re = '%
# Match a non-nested "{block:name:func(params)}...{/block:name}" structure.
(?P<opening> # $1: == $opening: BLOCK start tag.
{ # BLOCK tag opening literal "{"
(?P<inverse>[!])? # $2: == $inverse: Optional "!" negation.
block: # Opening BLOCK tag ident.
(?P<name>[a-z0-9\s_-]+) # $3: == $name: BLOCK element name.
( # $4: Optional BLOCK function.
: # Function name preceded with ":".
(?P<function>[a-z0-9\s_-]+) # $function: Function name.
( # $5: Optional function parameters.
[\s]? # Allow one whitespace before (params).
\( # Literal "(" params opening char.
(?P<params>[^)]*) # $6: == $params: function parameters.
\) # Literal ")" params closing char.
)? # End $5: Optional function parameters.
)? # End $4: Optional BLOCK function.
} # BLOCK tag closing literal "}"
) # End $1: == $opening: BLOCK start tag.
(?P<contents> # $contents: BLOCK element contents.
[^{]* # {normal) Zero or more non-"{"
(?: # Begin {(special normal*)*} construct.
\{ # {special} Allow a "{" but only if it is
(?!/?block:[a-z0-9\s_-]+\}) # not a BLOCK tag opening literal "{".
[^{]* # More {normal}
)* # Finish "Unrolling-the-Loop" (See: MRE3).
) # End $contents: BLOCK element contents.
(?P<closing> # $closing: BLOCK element end tag.
{ # BLOCK tag opening literal "{"
/block: # Closing BLOCK tag ident.
(?P=name) # Close name must match open name.
} # BLOCK tag closing literal "}"
) # End $closing: BLOCK element end tag.
%six';
$text = file_get_contents('testdata.html');
if (preg_match($re, $text, $matches)) print_r($matches);
else echo("no match!");
?>
追加のインデントとコメントにより、正規表現が何をしようとしているのかを実際に理解できることに注意してください。私のテストでは、正規表現に問題はなく、宣伝どおりに機能することが示されています。Jeffrey Friedl の高度な「Unrolling-the-Loop」効率化手法も実装されているため、これを書いた人は本物の正規表現スキルを持っています。
たとえば、元の質問から取得した次のデータがあるとします。
<ul>{block:menu}
<li><a href="{var:link}">{var:title}</a>
{/block:menu}</ul>
スクリプトからの(正しい)出力は次のとおりです。
'''
Array
(
[0] => {block:menu}
<li><a href="{var:link}">{var:title}</a>
{/block:menu}
[opening] => {block:menu}
[1] => {block:menu}
[inverse] =>
[2] =>
[name] => menu
[3] => menu
[4] =>
[function] =>
[5] =>
[6] =>
[params] =>
[7] =>
[contents] =>
<li><a href="{var:link}">{var:title}</a>
[8] =>
<li><a href="{var:link}">{var:title}</a>
[closing] => {/block:menu}
[9] => {/block:menu}
)
'''
function
オプションのandparams
がテスト データに含まれている場合にも機能します。
とはいえ、質問/正規表現にはいくつかの問題があります。
- 正規表現は、名前付きのキャプチャ グループと番号付きのキャプチャ グループを混在させています。
{
とはメタ文字であり、}
エスケープする必要があります (ただし、この場合、PCRE は文字どおりに解釈する必要があると正しく判断できます)。
- オプションでキャプチャされたグループをユーザーがどのように使用するかは不明です。
- OPがこの正規表現を使用する際にどのような問題を抱えているかは不明です。