本文详解 `numb3rs.py` 中 ipv4 地址验证逻辑的常见缺陷,指出原正则未严格约束每个八位组(octet)的取值范围及整体结构,导致 `test_numb3rs.py` 误判;提供健壮、可读性强的正则优化方案,并说明预编译与模式复用的最佳实践。
原代码中 validate() 函数使用的正则表达式虽看似覆盖了 0–255 范围,但存在两个关键问题:
✅ 正确做法是:将单个合法八位组抽象为独立模式,再通过 r'\.'.join(...) 动态拼接四次,并用 re.compile() 预编译提升性能与可读性。
以下是优化后的完整实现:
import re
# 单个 IPv4 八位组:0–255,支持前导零(如 "001"),但拒绝 "012"(即不校验前导零语义,仅校验数值范围)
IPV4_OCTET_PATTERN = r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
# 构建完整 IPv4 模式:^octet.octet.octet.octet$
IPV4_PATTERN = re.compile(r'^' + r'\.'.join([IPV4_OCTET_PATTERN] * 4) + r'$')
def main() -> None:
ip_address = input("IPv4 Address: ")
print(validate(ip_address))
def validate(ip_address: str) -> bool:
"""验证字符串是否为语法合法的 IPv4 地址(不校验语义前导零,仅数值范围与结构)"""
return bool(IPV4_PATTERN.match(ip_address))
if __name__ == "__main__":
main()? 关键改进说明:
? 验证测试建议(补充至 test_numb3rs.py):
def test_edge_cases():
assert validate("0.0.0.0") is True
assert validate("255.255.255.255") is True
assert validate("01.02.03.04") is True # 允许前导零(题目未禁用)
assert validate("1.1.1.1.1") is False
assert validate("1.1.1.") is False
assert validate("256.1.1.1") is False
assert validate("-1.1.1.1") is False
assert validate("1.1.1") is False✅ 最终效果:所
