[英]Regex find pattern between blocks
我正在用PHP(类似于Django)构建一个模板引擎,以其相关数据替换{{ }}
之间的所有内容。 现在,我能够做到这一点,但是我面临的情况是,仅需要在块之间进行替换,例如{% for y in x %}
循环块,并且忽略了不在它们之间的所有括号。
在这个regex101示例中,我可以得到一些结果,但是只能得到每个块的第一个{{ }}
。 我想做的是匹配每个块中的所有{{ }}
,不包括外部的。
出于学习目的(非常好!),您有几种可能:
多步骤方法(易于理解和维护):
整体正则表达式解决方案(更复杂,甚至可能更“花哨”)
将块与以下表达式匹配(请参阅regex101.com上的演示 ):
{{\s*(.+?)\s*}}
并在每个块中查找成对的{{...}}
, 其中包括:
<?php
$data = <<<DATA
{% for user in users %}
Hello, {{ user.name }}, you are {{ user.age }} {{ user.name }}
ssssssssssssssssssssss {{ user.name }}
sdsddddddddddddddddddddddddddddd
{% endfor %}
{% for dog in dogs %}
Your dog is {{ dog.age }} and likes {{ dog.food }}.
{% endfor %}
wwww
{{ user.name }}
DATA;
$block = '~
{%\ for.*?%}
(?s:.+?)
{%\ endfor.*?%}
~x';
$variable = '~{{\s*(.+?)\s*}}~';
if (preg_match_all($block, $data, $matches)) {
foreach ($matches as $match) {
if (preg_match_all($variable, $match[0], $variables, PREG_SET_ORDER)) {
print_r($variables);
}
}
}
?>
在PHP
,这可能是:
<?php $data = <<<DATA {% for user in users %} Hello, {{ user.name }}, you are {{ user.age }} {{ user.name }} ssssssssssssssssssssss {{ user.name }} sdsddddddddddddddddddddddddddddd {% endfor %} {% for dog in dogs %} Your dog is {{ dog.age }} and likes {{ dog.food }}. {% endfor %} wwww {{ user.name }} DATA; $block = '~ {%\\ for.*?%} (?s:.+?) {%\\ endfor.*?%} ~x'; $variable = '~{{\\s*(.+?)\\s*}}~'; if (preg_match_all($block, $data, $matches)) { foreach ($matches as $match) { if (preg_match_all($variable, $match[0], $variables, PREG_SET_ORDER)) { print_r($variables); } } } ?>
将所有有问题的变量与一个整体表达式匹配。 在这里,您将需要\\G
(在最后一场比赛的位置匹配)和一些先行动作(也可以在regex101.com上查看此示例的演示 ):
(?:{%\\ for.+?%} | \\G(?!\\A) ) (?s:(?!{%).)*?\\K {{\\s*(?P<variable>.+?)\\s*}}
现在让我们揭开这个表达式的神秘面纱:
(?:{%\\ for.+?%} | \\G(?!\\A) )
在这里,我们要匹配{%\\ for.+?%}
(我们需要使用\\
因为我们处于详细模式), 或者要匹配最后一个与\\G
匹配的位置。 现在,事实是\\G
在最后匹配的位置或字符串的最开始匹配。 我们不希望后者,因此不想要。 前瞻(?!\\A)
下一部分
(?s:(?!{%).)*?\\K
一种“快速前进”到所关注的有趣部分。
坏了,这说
(?s: # open a non-capturing group, enabling the DOTALL mode (?!{%). # neg. lookahead, do not overrun {% (the closing tag) )*? # lazy quantifier for the non-capturing group \\K # make the engine "forget" everything to the left
现在,剩下的事情很简单了:
{{\\s*(?P<variable>.+?)\\s*}}
基本上,其结构与广告1)相同。
同样,在PHP
,这可能是:
<?php $regex = '~ (?:{%\\ for.+?%} | \\G(?!\\A) ) (?s:(?!{%).)*?\\K {{\\s*(?P<variable>.+?)\\s*}} ~x'; if (preg_match_all($regex, $data, $variables)) { print_r($variables[1]); } ?>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.