在this regex101 demo中,我试图获取每个块的内容:
{% block works %}
This works
{% endblock %}
{% block main_block %}
{% block sub_block %}
Does not work
{% endblock %} #ends here
This is not covered
{% endblock %}
如果块内部没有块,它可以正常工作,但是,在第二个块(main_block)中,它无法匹配其所有内容,因为在内部找到了一个块。
我需要一个捕获main_block和sub_block块的正则表达式模式,而不会在第一个{%endblock%}标记上结束。
现在,我的表达式如下:\{\%\s*block\s?([a-z0-9\_]*?)\s?\%\}(.*?)(?>(?:{\%\s*block\s?([a-z0-9\_]*?)\s?\%\}|(?R))*\{\%\s?endblock\s?\1?\s?\%\}\is
编辑:我的问题被标记为重复,但我不认为它与该问题有关,我的情况不同,其中块可能无限期地在块内。
答案 0 :(得分:0)
使用正则表达式:'/(\ *){%\sblock.*\s%}((?:.*|\n)*?)\1{%\sendblock.*\s%}/'
为了使其工作,它确实假设块格式正确,但如果它们格式正确,这在大多数情况下都有效(它使用每个块之前的空格来确定标签是否匹配)。 / p>
尝试这个尺寸:
<?php
function getBlockText($blockText)
{
$regex = '/(\ *){%\sblock.*\s%}((?:.*|\n)*?)\1{%\sendblock.*\s%}/';
$recursedMatches= [];
preg_match_all($regex, $blockText, $matches);
for ($i = 0; $i < count($matches[2]); $i++) {
if(preg_match($regex, $matches[2][$i])){
array_push($recursedMatches, getBlockText($matches[2][$i]));
} else {
array_push($recursedMatches, $matches[2][$i]);
}
}
return $recursedMatches;
}
$str = '{% block works %}
This works
{% endblock %}
{% block main_block %}
{% block sub_block %}
Does not work
{% endblock %} #ends here
This is not covered
{% block sub_block %}
Does not work
{% endblock %}
{% endblock %}';
print_r(getBlockText($str));
输出:
Array
(
[0] =>
This works
[1] => Array
(
[0] =>
Does not work
[1] =>
Does not work
)
)