如何匹配逗号分隔字符串中的合法IP地址,修正正则截断错误?
问题原因
现有正则的核心问题是没有对匹配结果的前后做边界限制,匹配时只要找到符合规则的连续字符就会返回,不会管后续字符是否合法。比如处理255.255.255.256时,前15位255.255.255.25完全符合原有正则规则,就会直接被作为匹配结果返回,忽略了最后一位多余的6。
修复方案
只需要调整正则表达式,增加前后零宽断言,限制匹配到的IP地址前后不能是数字或小数点即可,修改后的完整代码如下:
import re # 调整后的正则,增加前后边界限制,避免截断匹配 ip_pattern = re.compile(r"(?<![\d.])(?:(25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)(?![\d.])") def get_ip_by_regex(ip_str): """从给定文本中匹配IP地址并返回 :param ip_str: 示例输入 "255.255.255.255,255.255.255.256,260.255.255.255" :type ip_str: 字符串 :return: 符合规则的IP列表 ["255.255.255.255"] :rtype: list[string] """ ret = [] for match in ip_pattern.finditer(ip_str): ret.append(match.group()) return ret # 测试代码 if __name__ == "__main__": test_str = "255.255.255.255,255.255.255.256,260.255.255.255" print(get_ip_by_regex(test_str)) # 输出 ['255.255.255.255']
正则修改说明
- 开头增加
(?<![\d.]):零宽负向回顾后发断言,要求匹配到的IP开头前一位不能是数字或小数点,避免从长数字/IP段中间截取内容 - 结尾增加
(?![\d.]):零宽负向先行断言,要求匹配到的IP结尾后一位不能是数字或小数点,避免类似256被截断为25的问题 - 把原有捕获组改成非捕获组
(?:),避免不必要的分组捕获,提升匹配效率
内容的提问来源于stack exchange,提问作者sususama5555
相关产品推荐
相关产品推荐

