0

Twigに似たテンプレート構造があります。私はこれを現在成功している正規表現で分けます。

{% for array as item %}
    {% item.party %}
    {% item %}
{% else %}
    // If empty...
{% endfor %}

{% if !var %}
   // Full
{% else %}
   // Empty
{% endif %}

// Is var full, replace block whit var
{% block var %}
   Some Code
{% endblock %}

正規表現 preg_match_all('/(?:{% (for|if|block) )(.*?)(?: %})(.*?)({% else %}(.*?))?(?:{% end\1 %})/is', $content, $data);

さて、それも入れ子にできるようにしたいと思います。唯一の問題は、ループが常に間違った方向に進むことです。外側のループは最初なので、内側の端を取ります。

{% for array as item %} // From here on
   {% item.title %}
   {% for item.sub as sub %}
      {% sub.title %}
   {% endfor %} // To here
{% endfor %}

正規表現で正しい端を選択する方法を知っていますか?最初のレベルのコンテンツでは、関数全体を再適用することもできます。ただし、正しい端を使用するには正規表現である必要があります。

4

1 に答える 1

1

以下はあなたの要件を満たしているようです。

これは(?R)、ブロック内の式全体の再帰的マッチングを可能にするために使用します。再帰パターンPCRE
を参照してください。

preg_match_all(
    '/(?:{% (for|if|block) )(.*?)(?: %})(?:(?R)|(.*?)({% else %}(.*?))?)*(?:{% end\1 %})/is',
     $content, $data
);

私があなたの表現に加えた唯一の変更は、非キャプチャグループのブロックの内部コンテンツサブパターンを囲み、(R)それに代替を追加するための追加でした。

start(?:(?R)|inner)end

(?R)正規表現全体を照合し、それによって外側のブロック内の他のブロックを照合しようとします。

(?R)を括弧で囲むこともできます。つまり((?R))、これらの内側のブロックは3番目のキャプチャグループで使用できます。

于 2013-03-03T22:57:49.863 に答える