如何编写/修正正则表达式以匹配模板引擎中[%与]范围内的目标属性(含多运算符及无等号场景)
解决模板引擎属性提取的正则方案
我来帮你搞定这个模板属性提取的问题!针对你提到的两种提取需求(带运算符的条件属性、大小写转换指令后的属性),我们可以通过分阶段正则匹配的方式精准实现,完美处理空格、嵌套括号这些复杂场景。
整体思路
- 先把所有
[%...]格式的模板指令块从HTML中提取出来,完全避开HTML自身的class/id等属性; - 对每个指令块,分别匹配两种类型的属性:
- 条件语句(
if/elseif)中,运算符(=/<=/>=/!=)前的属性; uppercase/lowercase指令后的属性。
- 条件语句(
具体正则与实现
第一步:提取所有模板指令块
用非贪婪匹配提取[%和]之间的内容,避免把多个指令块合并成一个:
\[\%(.*?)\]
第二步:匹配条件语句中的属性
这个正则专门捕捉条件里的属性,支持属性和运算符之间有任意空格,也能处理嵌套括号里的属性:
(?:\(|\s)(\w+)\s*(?:=|<=|>=|!=)
(?:\(|\s):匹配属性的前置分隔符(左括号或空格),非捕获组不会干扰结果;(\w+):捕获属性名(假设属性由字母、数字、下划线组成,符合你示例里的命名规则);\s*:匹配属性和运算符之间的0到多个空格;(?:=|<=|>=|!=):匹配目标运算符,非捕获组只做匹配不捕获。
第三步:匹配大小写转换指令的属性
这个正则精准捕捉uppercase/lowercase后面的属性,支持指令和属性之间的空格:
\b(?:uppercase|lowercase)\s*(\w+)\b
\b:单词边界,避免误匹配类似uppercaseabc这种错误格式;(?:uppercase|lowercase):匹配指令关键字;\s*:匹配关键字和属性之间的任意空格;(\w+):捕获属性名。
示例代码(Python)
把上面的正则整合起来,用代码实现提取:
import re # 你的模板内容 template = '<html> <body> <h1 class="title">Some Title</h1> <div id="output"> [%if findthis1=\'123\'] Bla bla bla ["findthis2"] Bla Bla Bla [%elseif (findthis3 = "123")] Bla Bla Bla [\'findthis4\'] Bla Bla Bla [%elseif ( findthis5 = "123" )] Bla Bla Bla [findthis6] Bla Bla Bla [%elseif ( findthis7 = "123" OR findthis8 = 123 ) AND findthis9=\'123\'] [findthis10] Bla Bla Bla [%elseif ( findthis11 = "123" OR ( findthis12=123 AND findthis13=\'123\' ) ] Bla Bla Bla [findthis14] [%endif] [%uppercase findthis15] [%lowercase findthis16 ] </div> </body> </html>' # 1. 提取所有[%...]指令块 block_pattern = re.compile(r'\[\%(.*?)\]') blocks = block_pattern.findall(template) # 2. 定义属性匹配正则 condition_attr_re = re.compile(r'(?:\(|\s)(\w+)\s*(?:=|<=|>=|!=)') case_attr_re = re.compile(r'\b(?:uppercase|lowercase)\s*(\w+)\b') # 收集所有属性(用集合去重) all_attributes = set() for block in blocks: # 提取条件属性 condition_attrs = condition_attr_re.findall(block) all_attributes.update(condition_attrs) # 提取大小写转换属性 case_attrs = case_attr_re.findall(block) all_attributes.update(case_attrs) # 输出结果 print("提取到的属性:", sorted(all_attributes))
运行后会得到结果:
提取到的属性: ['findthis1', 'findthis10', 'findthis11', 'findthis12', 'findthis13', 'findthis15', 'findthis16', 'findthis3', 'findthis5', 'findthis7', 'findthis8', 'findthis9']
为什么之前的正则失效?
你之前用的正则过于贪婪,且没有明确属性名的匹配规则,导致误匹配了很多无关内容。现在我们用\w+明确属性名的格式,结合前置分隔符(括号/空格),既能精准捕获目标属性,又能避开HTML自身的属性。
内容的提问来源于stack exchange,提问作者user3033043
相关产品推荐
相关产品推荐

