Ansible-lint自定义正则规则误匹配问题求助
问题描述
我想要使用Ansible-lint检查YAML文件中的子网格式是否正确,正确格式示例为10.10.10.0/32,错误格式为10.10.10.0 /32(斜杠前存在空格)。我编写了如下自定义规则:
from ansiblelint import AnsibleLintRule import re class CheckCustomPattern(AnsibleLintRule): id = 'CUSTOM005' shortdesc = 'Check if pattern "\s/[1-3][0-9]" is found' description = 'This rule checks if the pattern "\s/[1-3][0-9]" is found in any file.' severity = 'HIGH' tags = ['files'] def match(self, file, text): with open(file['path'], 'r') as file_content: content = file_content.read() if re.search(r'\s/[1-3][0-9]', content): return True return False
我已在正则测试工具中验证该正则表达式正确,但运行该规则时,它会匹配所有IP地址(包括格式正确的),甚至匹配非IP类字符串,例如[ TCP UDP ICMP ],不清楚问题出在哪里。
问题分析与解决
问题1:正则表达式范围过于宽泛
你当前使用的正则r'\s/[1-3][0-9]'仅匹配“空白字符+/+1-3开头的两位数字”,既没有限定该模式必须出现在IP地址的结尾(即前面是数字),也没有覆盖合法子网掩码的完整范围(子网掩码合法值是0-32,你的正则会漏掉/0到/9的情况,还错误包含了/33到/39的非法值)。这会导致任何包含“空格+/+1-3开头两位数字”的内容都会被误判,若测试文件中存在其他符合该模式的无关内容,也会被匹配。
问题2:重复读取文件内容
Ansible-lint的match方法已经通过第二个参数text传入了文件内容,无需再次打开文件读取,重复读取可能引发编码或文件状态相关的问题。
修正后的规则代码
from ansiblelint import AnsibleLintRule import re class CheckCustomPattern(AnsibleLintRule): id = 'CUSTOM005' shortdesc = 'Check for invalid subnet format (space before slash)' description = 'Ensure subnets follow the format x.x.x.x/xx, no space allowed before the slash.' severity = 'HIGH' tags = ['files', 'formatting'] def match(self, file, text): # 匹配IP最后一段数字后带空格,再跟/和合法子网掩码(0-32)的情况 invalid_pattern = re.compile(r'\d\s/([0-9]|[1-2][0-9]|3[0-2])') return invalid_pattern.search(text) is not None
说明
- 修正后的正则
r'\d\s/([0-9]|[1-2][0-9]|3[0-2])'会精准匹配:数字(IP地址的最后一段)+ 空格 + / + 合法的子网掩码(0-32),避免误匹配无关内容。 - 直接使用
match方法传入的text参数,无需手动读取文件,符合Ansible-lint的规则编写规范。
内容的提问来源于stack exchange,提问作者Dan Carlton
相关产品推荐
相关产品推荐

