靠谱的IPv4正则为^(?:(?:25[0-5]|20-4|[01]?0-9?).){3}(?:25[0-5]|20-4|[01]?0-9?)$,它分三类精确匹配0–255范围,用^$确保全串匹配,并推荐优先使用filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)配合trim()。

匹配IPv4地址的正则怎么写才靠谱
直接用 ^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$ 是错的——它会匹配 999.999.999.999 这种非法IP。真正可用的正则必须校验每段数字在 0–255 范围内。
推荐这个: ^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
- 每段都分三类处理:
25[0-5](250–255)、2[0-4][0-9](200–249)、[01]?[0-9][0-9]?(0–199,但靠前面的分支已排除高位冲突) - 开头
^和结尾$强制全字符串匹配,避免192.168.1.1abc这类误匹配 - 注意括号里用了非捕获组
(?:...),避免无谓的分组开销
PHP里用 preg_match 怎么调用
别漏掉定界符和修饰符。最常用的是加 i(虽然IP没大小写,但习惯保留)和 u(兼容UTF-8输入)。
if (preg_match('/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/i', $ip, $matches)) {
echo "合法IP:", $matches[0];
}
- 如果只验证不提取,
$matches可以省略;但留着方便后续调试 - 注意斜杠
/是定界符,不能少,也不能跟在变量后拼接(易出错),建议写死 - 不要用
eregi()——PHP 7.0+ 已移除,且早就不推荐
为什么不用 filter_var($ip, FILTER_VALIDATE_IP)
因为 filter_var 更可靠、更简洁,还支持 IPv6 和子网掩码校验。除非你被要求“必须用正则”,否则优先选它。
立即学习“PHP免费学习笔记(深入)”;
-
filter_var($ip, FILTER_VALIDATE_IP)自动处理前导零问题(如192.168.01.1→ 拒绝) - 要限定只 IPv4:
filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) - 它底层不是正则,性能略好,且行为稳定——不像手写正则容易漏边界(比如
0.0.0.0或255.255.255.255是否允许,得看业务需求)
常见踩坑点:前导零、空格、换行符
用户输入往往带空格或不可见字符,trim() 必须做,否则 " 127.0.0.1 " 会匹配失败。
- 别忘了
trim($ip)再传给正则或filter_var - IPv4 不允许前导零(
192.168.001.001是非法的),但filter_var默认拒绝,而手写正则若没严格限制会放过 - 换行符如
"127.0.0.1\n"会被$拦住——所以trim()不只是美观,是功能必需
trim(),再 filter_var(..., FILTER_VALIDATE_IP, FILTER_FLAG_IPV4),比手写正则更省心也更少出错。手写正则只在需要提取多段、或嵌入其他复杂模式时才值得投入。



















