常用正则表达式-IP地址

1. IPv4地址

1. IPv4地址定义

参考百度百科

IPv4使用32位(4字节)地址,因此地址空间中只有4,294,967,296(即2的32次方)个地址。

通常使用点分十进制进行表示方法,如0.0.0.0-255.255.255.255。

2. IPv4地址的正则表达式

一个合法的IPv4地址由4组数字组成,每组数字之间以.隔开,数字的取值范围为0-255。每组数字的总结如下:

范围描述正则表达式
0-91位数字\d
10-992位数字[1-9]\d
100-199以1开头的3位数字1\d{2}
200-249以2开头,第2位是0-4的3位数字2[0-4]\d
250-25525开头,第3位是0-5的3位数字25[0-5]

所以每组数字的正则表达式为:

(\d)|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5])

注:每种情况务必加上(),因为元字符|对邻接的字符/字符集/子表达式都起作用。
进而,IPv4的完整正则表达式为:

(((\d)|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}((\d)|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))

对应java代码的正则为:

String IP_V4 = "^(((\\d)|([1-9]\\d)|(1\\d{2})|(2[0-4]\\d)|(25[0-5]))\\.){3}((\\d)|([1-9]\\d)|(1\\d{2})|(2[0-4]\\d)|(25[0-5]))$"

3. 对应java代码

IPValidator.java

package com.ysx.utils.pattern;

import java.util.regex.Pattern;

/**
 * @author youngbear
 * @email youngbear@aliyun.com
 * @date 2022-09-04 17:54
 * @blog <a href="https://blog.csdn.net/next_second">...</a>
 * @github <a href="https://github.com/YoungBear">...</a>
 * @description IP校验
 */
public class IPValidator {

    private static final String IP_V4 = "^(((\\d)|([1-9]\\d)|(1\\d{2})|(2[0-4]\\d)|(25[0-5]))\\.){3}((\\d)|([1-9]\\d)|(1\\d{2})|(2[0-4]\\d)|(25[0-5]))$";
    // 下边这个正则也ok
    // private static final String IP_V4 = "^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$";
    private static final Pattern IP_V4_PATTERN = Pattern.compile(IP_V4);

    /**
     * 是否是有效的ipv4地址
     *
     * @param input 字符串
     * @return 是否是有效的ipv4地址
     */
    public static boolean isValidIpv4(String input) {
        if (input == null) {
            return false;
        }
        return IP_V4_PATTERN.matcher(input).matches();
    }
}

使用junit5单元测试:IPValidatorTest.java

package com.ysx.utils.pattern;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
 * @author youngbear
 * @email youngbear@aliyun.com
 * @date 2022-09-04 17:58
 * @blog <a href="https://blog.csdn.net/next_second">...</a>
 * @github <a href="https://github.com/YoungBear">...</a>
 * @description
 */
public class IPValidatorTest {

    @ParameterizedTest(name = "#{index} - Run test with IPv4 = {0}")
    @MethodSource("validIPv4Provider")
    void test_ipv4_regex_valid(String ipv4) {
        assertTrue(IPValidator.isValidIpv4(ipv4));
    }

    @ParameterizedTest(name = "#{index} - Run test with IPv4 = {0}")
    @MethodSource("invalidIPv4Provider")
    void test_ipv4_regex_invalid(String ipv4) {
        assertFalse(IPValidator.isValidIpv4(ipv4));
    }

    static Stream<String> validIPv4Provider() {
        return Stream.of(
                "0.0.0.0",
                "0.0.0.1",
                "127.0.0.1",
                "1.2.3.4",              // 0-9
                "11.1.1.0",             // 10-99
                "101.1.1.0",            // 100-199
                "201.1.1.0",            // 200-249
                "255.255.255.255",      // 250-255
                "192.168.1.1",
                "192.168.1.255",
                "100.100.100.100");
    }

    static Stream<String> invalidIPv4Provider() {
        return Stream.of(
                "000.000.000.000",          // leading 0
                "00.00.00.00",              // leading 0
                "1.2.3.04",                 // leading 0
                "1.02.03.4",                // leading 0
                "1.2",                      // 1 dot
                "1.2.3",                    // 2 dots
                "1.2.3.4.5",                // 4 dots
                "192.168.1.1.1",            // 4 dots
                "256.1.1.1",                // 256
                "1.256.1.1",                // 256
                "1.1.256.1",                // 256
                "1.1.1.256",                // 256
                "-100.1.1.1",               // -100
                "1.-100.1.1",               // -100
                "1.1.-100.1",               // -100
                "1.1.1.-100",               // -100
                "1...1",                    // empty between .
                "1..1",                     // empty between .
                "1.1.1.1.",                 // last .
                "");                        // empty
    }
}

源代码地址

参考

1. Java IP Address (IPv4) regex examples

其他的ipv4地址的正则及问题

有问题的

// https://juejin.cn/post/6844903768232820749
// 有问题 00.00.00.00 认为是有效的
String IP_V4 = "^(((\\d{1,2})|(1\\d{2})|(2[0-4]\\d)|(25[0-5]))\\.){3}((\\d{1,2})|(1\\d{2})|(2[0-4]\\d)|(25[0-5]))$";

// http://www.java2s.com/example/java/java.util.regex/is-ipv4-address-by-regex.html
// -- 有问题 000.000.000.000 认为是合法的
String IPV4_PATTERN ="^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$"
// https://mkyong.com/regular-expressions/how-to-validate-ip-address-with-regular-expression/
String IPV4_PATTERN ="^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\\.(?!$)|$)){4}$"

正确的:

// https://mkyong.com/regular-expressions/how-to-validate-ip-address-with-regular-expression/  
  // 25[0-5]        = 250-255
  // (2[0-4])[0-9]  = 200-249
  // (1[0-9])[0-9]  = 100-199
  // ([1-9])[0-9]   = 10-99
  // [0-9]          = 0-9
  // (\.(?!$))      = can't end with a dot
  private static final String IPV4_PATTERN_SHORTEST =
          "^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\\.(?!$)|$)){4}$";      
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐