Рубрики
Без рубрики

Примеры регулярных выражений Java IP-адреса (IPv4)

В этой статье рассказывается о регулярном выражении IPv4, валидаторе Java IPv4, валидаторе Apache Commons и модульных тестах для списка допустимых адресов IPv4.

Автор оригинала: mkyong.

Эта статья посвящена тому, как проверить IP-адрес ( IPv4 ) с помощью регулярных выражений и средства проверки Apache Commons.

Вот краткое изложение.

  1. Объяснение регулярного выражения IPv4.
  2. Валидатор Java IPv4, использующий регулярное выражение.
  3. Валидатор Java IPv4, использующий commons-валидатор-1.7
  4. Модуль 5 модульные тесты для вышеуказанных валидаторов IPv4.

Окончательная версия регулярного выражения IPv4.

^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.(?!$)|$)){4}$
# Explanation
(
  [0-9]         # 0-9
  |             # or
  [1-9][0-9]    # 10-99
  |             # or
  1[0-9][0-9]   # 100-199
  |             # or
  2[0-4][0-9]   # 200-249
  |             # or
  25[0-5]       # 250-255
)
(\.(?!$)|$))    # ensure IPv4 doesn't end with a dot
{4}             # 4 times.

P.S Это регулярное выражение предназначено только для IPv4-адреса. Он не поддерживает подсеть IPv4 или IPv6.

1. Объяснение регулярного выражения IPv4.

Допустимый диапазон IPv4 составляет от 0.0.0.0 к 255.255.255.255 , нам нужно создать регулярное выражение, чтобы обеспечить число в диапазоне [0-255] и точки в правильном положении.

1.1 Ниже приведено первое регулярное выражение IPv4. Позже мы разовьем его в лучшую и более короткую версию.

  // version 1 allow leading zero, 01.01.01.01
  private static final String IPV4_PATTERN_ALLOW_LEADING_ZERO =
            "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
            "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";

1.2 В приведенном выше регулярном выражении используется \\d для сопоставления чисел 0-9 . Однако \\d также будет соответствовать номерам Юникода; в целях безопасности, пожалуйста, используйте [0-9] для соответствия только числам ASCII.

Ниже приведено регулярное выражение IPv4 версии 2.

  // version 2 , allow leading zero, 01.01.01.01
  private static final String IPV4_PATTERN_ALLOW_LEADING_ZERO =
            "^([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\." +
            "([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\." +
            "([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\\." +
            "([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])$";

Ниже приведено объяснение приведенного выше регулярного выражения.

^                       #  start of the line
  (                     #  start of group #1
    [01]?[0-9][0-9]?    #  can be one or two digits. If three digits appear, it must start either 0 or 1
    |                   #    ...or
    2[0-4][0-9]         #    start with 2, follow by 0-4 and end with any digit (2[0-4][0-9])
    |                   #    ...or
    25[0-5]             #    start with 2, follow by 5 and ends with 0-5 (25[0-5])
  )                     #  end of group  #1
  \\.                   #  follow by a dot "."
                        # repeat it 3 times (3x)
$                       # end of the line

1.3 Однако версии 1 и 2 поддерживают начальный ноль в адресе IPv4, например, 01.01.01.01 . Является ли ведущий ноль допустимым адресом IPv4?

Ниже приведено регулярное выражение IPv4 версии 3; оно не допускает начального нуля в адресе IPv4.

  // version 3, simple and easy to understand
  private static final String IPV4_PATTERN =
           "^([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\." +
           "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\." +
           "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\." +
           "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$";

Ниже приведено объяснение вышеупомянутого регулярного выражения; это утомительное и длинное регулярное выражение, но оно очень читабельно и очень легко для понимания.

(
  [0-9]         # 0-9
  |             # or
  [1-9][0-9]    # 10-99
  |             # or
  1[0-9][0-9]   # 100-199
  |             # or
  2[0-4][0-9]   # 200-249
  |             # or
  25[0-5]       # 250-255
)
\\.             # follow by a dot
                # repeat 3 times.

1.4 Ниже приведено регулярное выражение IPv4 версии 4; оно работает так же, как и приведенная выше версия 3, только немного короче регулярного выражения с повторением {3} .

  // version 4
  private static final String IPV4_PATTERN =
            "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}" +
            "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$"

1.5 Ниже приведено регулярное выражение IPv4 версии 5, окончательная версия. Он работает так же, как версии 3 и 4, но короче и дополнительно (\\.(?!$)|$) чтобы убедиться, что IPv4 не заканчивается точкой.

  //version 5
  private static final String IPV4_PATTERN =
            "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\\.(?!$)|$)){4}$";

Примечание Пожалуйста, обратитесь к приведенным ниже модульным тестам № 4 для получения списка допустимых и недопустимых IPv4-адресов.

Дополнительный Ниже приведена гораздо более короткая версия регулярного выражения IPv4, просто для справки. Тем не менее, я по-прежнему предпочитаю вышеуказанное регулярное выражение IPv4 окончательной версии 3 и версии 5.

  // 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}$";          

P.S Пожалуйста, не используйте регулярное выражение, если вы не понимаете, как оно работает.

2. Валидатор регулярных выражений Java IPv4

Ниже приведен пример средства проверки регулярных выражений Java IPv4. Он использует вышеупомянутое регулярное выражение IPv4 версии 5 для проверки адреса IPv4.

package com.mkyong.regex.ipv4;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class IPv4ValidatorRegex {

    private static final String IPV4_PATTERN =
            "^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\\.(?!$)|$)){4}$";

    private static final Pattern pattern = Pattern.compile(IPV4_PATTERN);

    public static boolean isValid(final String email) {
        Matcher matcher = pattern.matcher(email);
        return matcher.matches();
    }

}

3. IPv4 Валидатор – Валидатор Apache Commons

В этом примере используется средство проверки Apache Commons для проверки адреса IPv4.

  
      commons-validator
      commons-validator
      1.7
  

Ниже приведен другой валидатор IPv4 Java, использующий API-интерфейсы commons-validator для проверки адреса IPv4.

package com.mkyong.regex.ipv4;

import org.apache.commons.validator.routines.InetAddressValidator;

public class IPv4ValidatorApache {

    private static final InetAddressValidator validator
                              = InetAddressValidator.getInstance();

    public static boolean isValid(final String ip) {

        // only IPv4
        return validator.isValidInet4Address(ip);

        // IPv4 + IPv6
        // return validator.isValid(ip);

        // IPv6 only
        // return validator.isValidInet6Address(ip);
    }

}

Внутренне, InetAddressValidator использует простое регулярное выражение и ручную проверку для проверки адреса IPv4.

public class InetAddressValidator implements Serializable {

  private static final String IPV4_REGEX =
              "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$";

  //...

  public boolean isValidInet4Address(String inet4Address) {
      // verify that address conforms to generic IPv4 format
      String[] groups = ipv4Validator.match(inet4Address);

      if (groups == null) {
          return false;
      }

      // verify that address subgroups are legal
      for (String ipSegment : groups) {
          if (ipSegment == null || ipSegment.length() == 0) {
              return false;
          }

          int iIpSegment = 0;

          try {
              iIpSegment = Integer.parseInt(ipSegment);
          } catch(NumberFormatException e) {
              return false;
          }

          if (iIpSegment > IPV4_MAX_OCTET_VALUE) {
              return false;
          }

          if (ipSegment.length() > 1 && ipSegment.startsWith("0")) {
              return false;
          }

      }

      return true;
  }

4. Модульные тесты (JUnit 5)

Ниже приведены параметризованные тесты JUnit 5 для вышеупомянутых валидаторов Java – валидатор регулярных выражений IPv4 #2 и валидатор Apache Commons #3.

  
  
      org.junit.jupiter
      junit-jupiter-params
      5.4.0
      test
  
package com.mkyong.regex.ipv4;

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;

public class IPv4ValidatorTest {

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

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

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

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

    static Stream 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 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
    }

}

Все модульные тесты пройдены.

Скачать Исходный Код

$клон git $клон git

$cd java-регулярное выражение/ipv4

Рекомендации

Оригинал: “https://mkyong.com/regular-expressions/how-to-validate-ip-address-with-regular-expression/”