如何用Twig拆分HTML块并包裹div?现有代码问题求助
解决Twig拆分内容并保留H2标签的问题
你的问题核心是拆分时丢失了<h2>标签,因为原代码直接用<h2>作为分隔符,导致标签本身被拆分掉了。下面提供两种可靠的解决方案,适配你存储的转义后HTML内容:
方法一:字符串替换+拆分(无需正则,兼容性好)
这种方法通过先在每个<h2>前插入特殊标记,再拆分,完美保留标签:
<section class="preparation"> {% set splitMarker = '<!--BLOCK_SPLIT-->' %} {# 先把转义的HTML实体转回真实标签 #} {% set rawContent = contentBlock|unescape('html') %} {# 在每个<h2>前添加拆分标记 #} {% set modifiedContent = rawContent|replace({'<h2>': splitMarker ~ '<h2>'}) %} {% for contentBlockItem in modifiedContent|split(splitMarker) %} {# 过滤掉可能的空块 #} {% if contentBlockItem|trim != '' %} <div class="block"> {{ contentBlockItem|raw }} </div> {% endif %} {% endfor %} </section>
步骤说明:
|unescape('html'):把变量里的<h2>转成真实的<h2>标签,否则拆分逻辑无法识别。- 插入拆分标记:确保每个区块都从
<h2>开始,包括标签本身。 - 拆分后过滤空块:避免原内容开头的空字符串生成多余的div。
|raw:确保HTML内容被正常渲染,不会再次转义。
方法二:正则匹配(更精准)
如果你的Twig环境支持正则函数(比如Symfony项目默认启用),可以用正则直接匹配每个完整的H2区块:
<section class="preparation"> {# 先转回真实HTML标签 #} {% set rawContent = contentBlock|unescape('html') %} {# 匹配所有从<h2>开始到下一个<h2>或内容结束的区块 #} {% set blocks = rawContent|preg_match_all('/<h2>.*?<\/h2>.*?(?=<h2>|$)/s') %} {% for block in blocks[0] %} <div class="block"> {{ block|raw }} </div> {% endfor %} </section>
正则说明:
/<h2>.*?<\/h2>.*?(?=<h2>|$)/s:<h2>.*?<\/h2>:匹配完整的H2标签及其内容。.*?(?=<h2>|$):匹配H2之后的内容,直到下一个H2或内容结束(非贪婪模式,避免过度匹配)。s修饰符:让.匹配换行符,确保跨多行的内容被正确捕获。
两种方法都能实现你要的效果:每个H2开头的区块被包裹在class="block"的div里,同时完整保留H2标签和所有内容。
内容的提问来源于stack exchange,提问作者ganar
相关产品推荐
相关产品推荐

