我正在使用PHP构建一个模板引擎(类似于Django),用{
"AAL": {
"station_code":"AAL",
"id": "32313",
"airport_name": "Aalborg",
"latitude": "57.1",
"longitude": "9.85",
"timezone": "2",
"dst_indicator": "E",
"city": "Aalborg",
"country": "Denmark",
"country_code": "DK",
"region": "TC1",
"listing_display": "true",
"pseudonyms": ""
},
"AAR": {
"station_code":"AAR",
"id": "32314",
"airport_name": "Tirstrup",
"latitude": "56.15",
"longitude": "10.2167",
"timezone": "2",
"dst_indicator": "E",
"city": "Aarhus",
"country": "Denmark",
"country_code": "DK",
"region": "TC1",
"listing_display": "true",
"pseudonyms": ""
}
}
替换其相关数据之间的所有内容。现在我能够做到这一点,但我面临的情况是只需要在块之间进行替换,例如{{ }}
循环块,并忽略不在它们之间的所有括号。
我能够在this regex101 example中获得一些结果但只得到每个块的第一个{% for y in x %}
。我想要做的是匹配每个块中的所有{{ }}
,不包括外面的那些。
答案 0 :(得分:2)
出于学习目的(非常好!),您有几种可能性:
多步骤方法(更易于理解和维护):
整体正则表达式解决方案(更复杂,可能更多"花式")
<小时/> 广告1)
使用以下表达式匹配块(请参阅a demo on regex101.com):
{%\ for.*?%}
(?s:.+?)
{%\ endfor.*?%}
在每个块中查找成对的{{...}}
:
{{\s*(.+?)\s*}}
在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);
}
}
}
?>
<小时/> 广告2)
将所有相关变量与整体表达式匹配。在这里,您需要\G
(在最后一场比赛的位置匹配)和一些前瞻(参见a demo for this one at regex101.com as well):
(?:{%\ for.+?%}
|
\G(?!\A)
)
(?s:(?!{%).)*?\K
{{\s*(?P<variable>.+?)\s*}}
现在让我们揭开这个表达的神秘面纱:
(?:{%\ for.+?%}
|
\G(?!\A)
)
在这里,我们想要匹配{%\ for.+?%}
(我们需要\
,因为我们处于详细模式)或位于最后一次匹配{{1 }}。现在,事实是,\G
要么匹配最后一个匹配的位置,要么匹配字符串的最开头。我们不想要后者,因此是否定的。向前看\G
。
下一部分
(?!\A)
快速前进&#34;对有趣的部分。
分解,这说
(?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
它基本上与广告1的结构相同。
同样,在{{\s*(?P<variable>.+?)\s*}}
中,这可能是:
PHP
<小时/> 尽管如此,实际上学习更复杂的模式通常是一个好主意,但另一方面却不能重新发明轮子 - 总有一个人比你更聪明。我可能考虑过几个边缘案例等等。