【问题标题】:Match block inside block with pcre将块内的块与 pcre 匹配
【发布时间】:2018-07-14 05:50:34
【问题描述】:

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

编辑:我的问题被标记为重复,但我认为这与该问题无关,我的情况不同,块可能无限期地位于块内。

【问题讨论】:

  • 您不能单独使用正则表达式捕获每个块内容。但您可以先验证格式,然后通过 PHP 流程。 regex101.com/r/7pauyx/2
  • @KenWhite 示例数据在开头,编辑了问题并添加了正则表达式。谢谢你,抱歉信息不足。
  • 看看这个骗子帖子。你必须实现类似的东西
  • @hjpotter92 当前的欺骗甚至间接地没有解决这个问题,Java RegEx 不像 PCRE 不支持递归。

标签: php regex pcre


【解决方案1】:

使用的正则表达式:'/(\ *){%\sblock.*\s%}((?:.*|\n)*?)\1{%\sendblock.*\s%}/'

为此,它确实假设块的格式正确,但如果它们的格式正确,这在大多数情况下都会起作用(它使用每个块之前的空格来确定标签是否匹配)。

试试这个尺寸:

<?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

        )

)

【讨论】:

  • 您好,感谢您的回答。输出应返回“这未涵盖”作为 main_block 的内容。不是块的所有内容都被视为内容。就此而言,“#ends here”也应该被返回(尽管我用它来强调正则表达式在那里结束,而不是在最后一个 {% endblock %}。
猜你喜欢
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
  • 2021-02-07
  • 1970-01-01
  • 2017-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多