如何编写正则匹配首尾name相同的模板IF-ENDIF语句块?
解决方案
你可以通过正则的反向引用特性实现该需求,反向引用可以直接复用前面捕获组匹配到的内容,强制两处内容完全一致才能匹配成功。
修正后的正则表达式
/{% +([^ ]+) +IF: +(.*?) +%}([\s\S]*?){% +\1 +ENDIF +%}/gm
修改点说明
- 第一个捕获组从
(.*)改为([^ ]+):限定只捕获连续非空格字符作为块名称,避免贪婪匹配吞掉后续的IF标识。如果你的块名称允许包含空格,可以将该部分改为([^:]+?),匹配到IF:前的所有内容作为名称即可。 - 所有
.*/[\s\S]*后追加?转为非贪婪匹配:避免存在多个IF块时,正则一次性跨块匹配多组内容。 - 原最后一个捕获组
(.*)替换为\1:\1是对第一个捕获组内容的反向引用,只有ENDIF前的名称和IF前的名称完全一致时,才会命中匹配。
匹配效果验证
可正常匹配的合法块
{% user IF: role EQUALS admin %} <a href="/manage">管理入口</a> {% user ENDIF %}
不会误匹配的非法块(名称不对应)
{% user IF: role EQUALS admin %} <a href="/manage">管理入口</a> {% order ENDIF %}
内容的提问来源于stack exchange,提问作者noah1400
相关产品推荐
相关产品推荐

