Regex在regex101正常但Python中提取HTML属性异常,如何修复?
修复HTML属性拆分的正则表达式问题
原始HTML属性文本(包含标签名):
a href="#" class="s-navigation--item js-gps-track js-products-menu" aria-controls="products-popover" data-controller="s-popover" data-action="s-popover#toggle" data-s-popover-placement="bottom" data-s-popover-toggle-class="is-selected" data-gps-track="top_nav.products.click({location:2, destination:1})" data-ga="["top navigation","products menu click",null,null,null]" aria-expanded="false"使用的原始正则:
attr_regex = '(?:\w+[-\.]*)+(?:=+[\'\"][\w\d\s:;,$@#!\[\]^&?%*\/+(){}.=-]*[\'\"])*'问题:在Python中执行
re.findall(attr_regex, text)时,错误拆分出属性值内的片段(如top、navigation),但在regex101中可正常工作。
修复后的正则表达式
import re # 匹配所有HTML属性(排除开头的标签名) attr_regex = r'(?<=\s)[\w\-\:\.]+(?:=(?:[\'"]|")[\s\S]*?(?:[\'"]|"))?' text = 'a href="#" class="s-navigation--item js-gps-track js-products-menu" aria-controls="products-popover" data-controller="s-popover" data-action="s-popover#toggle" data-s-popover-placement="bottom" data-s-popover-toggle-class="is-selected" data-gps-track="top_nav.products.click({location:2, destination:1})" data-ga="[&quot;top navigation&quot;,&quot;products menu click&quot;,null,null,null]" aria-expanded="false"' elements = re.findall(attr_regex, text) print(elements)
修复说明
- 添加位置断言:用
(?<=\s)确保匹配内容前是空白字符,彻底避免匹配属性值内的单词片段,同时自动排除开头的标签名(如示例中的a),精准定位属性的起始边界。 - 优化属性名匹配:替换原有的属性名匹配规则为
[\w\-\:\.]+,完全贴合HTML属性名规范,支持字母、数字、连字符、下划线、冒号、点等合法字符。 - 改进属性值匹配逻辑:
- 兼容单引号、双引号以及HTML实体
"作为属性值的包裹符 - 使用
[\s\S]*?非贪婪匹配任意字符,确保完整捕获包含括号、逗号、转义实体等特殊内容的属性值,不会提前终止匹配。
- 兼容单引号、双引号以及HTML实体
- 支持无值属性:将属性值部分标记为可选(末尾加
?),适配disabled这类不需要赋值的HTML属性。
如果需要处理更极端的HTML场景(如属性值内包含未转义的引号),可基于此正则进一步调整,但上述方案已覆盖绝大多数常见的属性拆分需求。
内容的提问来源于stack exchange,提问作者RifloSnake
相关产品推荐
相关产品推荐

