正则表达式从树枝模板中提取块
RegEx to extract block from twig template
在 PHP 中,我想提取包含在 twig 块中的文本,我认为正则表达式是最有效的。
假设我有一个包含以下内容的文件“index.twig”:
{% block content %}
Content of the page...
{% endblock %}
此代码运行良好:
$input = file_get_contents("index.twig");
preg_match_all('/\{%\s*block\s*content\s*\%}([^\%}]*)\{%\s*endblock\s*\%}/', $input, $output);
$output 将包含预期结果。
但是,如果输入文件是这样的:
{% block content %}
{{ a_tag }}
Content of the page...
{% endblock %}
在这种情况下,结束符 }} 会破坏正则表达式并且 $output 为空。
任何关于正确正则表达式的线索?
提取块内容的另一种解决方案?
我想得到:
{{ a_tag }}
Content of the page...
您可以简单地将与 twig 标签匹配的所有内容替换为空字符串。这是一个例子:
<?php
$x = <<<EOT
{% block content %}
{{ a_tag }}
Content of the page...
{% endblock %}
EOT;
$x = preg_replace(['/\{%[^\{\}]*%\}\n*/m', '/\{\{[^\{\}]*\}\}\n*/m'], '', $x);
$y = preg_replace('/\{%[^\{\}]*%\}\n*/m', '', $x);
print $x;
print PHP_EOL;
print $y;
这是我从评论中使用的解决方案:
{%\h*block\h*content\h*%}\R((?:(?!{%\h*endblock\h*%}).*\R)*){%\h*endblock\h*%}
这里有 2 个用于设置正则表达式模式的有用链接:
使用 [^\%}]*
意味着您可以匹配除使用 negated character class 列出的任何字符,在本例中为 %
(您不必转义)和 }
.
使用该方法,您无法在块之间匹配 {{ a_tag }}
。
获取值的一种方法是匹配块的起始代码,直到第一次出现结束块。在你匹配所有不以端块模式开头的行之间。
您可以使用 \h
来匹配水平空白字符,使用 \R
来匹配任何 unicode 换行序列,而不是使用 \s
。
{%\h*block\h*content\h*%}\R((?:(?!{%\h*endblock\h*%}).*\R)*){%\h*endblock\h*%}
模式将匹配:
{%\h*block\h*content\h*%}\R
匹配块内容部分和一个换行符
(
捕获 组 1
(?:(?!{%\h*endblock\h*%}).*\R)*
如果该行不以结束块模式开头,则匹配整行和换行符
)
关闭组 1
{%\h*endblock\h*%}
匹配endblock部分
在 PHP 中,我想提取包含在 twig 块中的文本,我认为正则表达式是最有效的。
假设我有一个包含以下内容的文件“index.twig”:
{% block content %}
Content of the page...
{% endblock %}
此代码运行良好:
$input = file_get_contents("index.twig");
preg_match_all('/\{%\s*block\s*content\s*\%}([^\%}]*)\{%\s*endblock\s*\%}/', $input, $output);
$output 将包含预期结果。
但是,如果输入文件是这样的:
{% block content %}
{{ a_tag }}
Content of the page...
{% endblock %}
在这种情况下,结束符 }} 会破坏正则表达式并且 $output 为空。
任何关于正确正则表达式的线索?
提取块内容的另一种解决方案?
我想得到:
{{ a_tag }}
Content of the page...
您可以简单地将与 twig 标签匹配的所有内容替换为空字符串。这是一个例子:
<?php
$x = <<<EOT
{% block content %}
{{ a_tag }}
Content of the page...
{% endblock %}
EOT;
$x = preg_replace(['/\{%[^\{\}]*%\}\n*/m', '/\{\{[^\{\}]*\}\}\n*/m'], '', $x);
$y = preg_replace('/\{%[^\{\}]*%\}\n*/m', '', $x);
print $x;
print PHP_EOL;
print $y;
这是我从评论中使用的解决方案:
{%\h*block\h*content\h*%}\R((?:(?!{%\h*endblock\h*%}).*\R)*){%\h*endblock\h*%}
这里有 2 个用于设置正则表达式模式的有用链接:
使用 [^\%}]*
意味着您可以匹配除使用 negated character class 列出的任何字符,在本例中为 %
(您不必转义)和 }
.
使用该方法,您无法在块之间匹配 {{ a_tag }}
。
获取值的一种方法是匹配块的起始代码,直到第一次出现结束块。在你匹配所有不以端块模式开头的行之间。
您可以使用 \h
来匹配水平空白字符,使用 \R
来匹配任何 unicode 换行序列,而不是使用 \s
。
{%\h*block\h*content\h*%}\R((?:(?!{%\h*endblock\h*%}).*\R)*){%\h*endblock\h*%}
模式将匹配:
{%\h*block\h*content\h*%}\R
匹配块内容部分和一个换行符(
捕获 组 1(?:(?!{%\h*endblock\h*%}).*\R)*
如果该行不以结束块模式开头,则匹配整行和换行符
)
关闭组 1{%\h*endblock\h*%}
匹配endblock部分