Проверка IPv4-адресов с помощью регулярного выражения - PullRequest
52 голосов
/ 12 марта 2011

Я пытался получить эффективное регулярное выражение для проверки IPv4, но без особой удачи.Мне показалось, что в какой-то момент у меня было это с (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}, но это дает некоторые странные результаты:

$ grep --version
grep (GNU grep) 2.7
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.1
192.168.1.1
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.255
192.168.1.255
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.255.255
$ grep -E '\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?(\.|$)){4}\b' <<< 192.168.1.2555
192.168.1.2555

Я выполнил поиск, чтобы выяснить, было ли это уже задано и получено, но другие ответы кажутсяпросто покажи, как определить 4 группы из 1-3 чисел, или у меня не работает.

Ответы [ 32 ]

1 голос
/ 01 июня 2018
(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.){3}(((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2})))

Тест для поиска совпадений в тексте, https://regex101.com/r/9CcMEN/2

Ниже приведены правила, определяющие допустимые комбинации в каждом номере IP-адреса:

  • Любое одно- или двузначное число.
  • Любое трехзначное число, начинающееся с 1.

  • Любое трехзначное число, начинающееся с 2, если вторая цифра - 0 через 4.

  • Любое трехзначное число, начинающееся с 25, если третье число 0 через 5.

Давайте начнем с (((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.), набора из четырех вложенных подвыражений, и мы рассмотрим их в обратном порядке. (\d{1,2}) соответствует любому одно- или двузначному числу или числам от 0 до 99. (1\d{2}) соответствует любому трехзначному номеру, начинающемуся с 1 (1, за которым следуют любые две цифры) или цифрам от 100 до 199. (2[0-4]\d) соответствует номерам от 200 до 249. (25[0-5]) соответствует номерам от 250 до 255. Каждое из этих подвыражений заключено в другое подвыражение с | между каждым (так что одно из четырех подвыражений должно совпадать, а не все). После диапазона чисел приходит \., чтобы соответствовать ., а затем весь ряд (все варианты чисел плюс \.) заключаются в еще одно подвыражение и повторяются три раза с использованием {3}. Наконец, диапазон чисел повторяется (на этот раз без завершающего \.), чтобы соответствовать окончательному номеру IP-адреса. Ограничивая каждое из четырех чисел значениями от 0 до 255, этот шаблон действительно может соответствовать действительным IP-адресам и отклонять недопустимые адреса.

Выдержка из: Бен Форта. «Изучение регулярных выражений».


Если ни символ не требуется ни в начале, ни в конце IP-адреса, следует использовать метасимволы ^ и $ соответственно.

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

Тест для поиска совпадений в тексте, https://regex101.com/r/uAP31A/1

1 голос
/ 17 марта 2019

''» Этот код работает для меня, и так просто.

Здесь я взял значение ip и пытаюсь сопоставить его с регулярным выражением.

ip="25.255.45.67"    

op=re.match('(\d+).(\d+).(\d+).(\d+)',ip)

if ((int(op.group(1))<=255) and (int(op.group(2))<=255) and int(op.group(3))<=255) and (int(op.group(4))<=255)):

print("valid ip")

else:

print("Not valid")

Выше условия проверяет, превышает ли значение 255 для всех 4 октетов, тогда оно недопустимо. Но перед применением условия мы должны преобразовать их в целое число, так как значение находится в строке.

group (0) печатает сопоставленный вывод, тогда как group (1) печатает первое совпавшее значение, здесь оно равно «25» и так далее. '' '

1 голос
/ 05 апреля 2018

с маской подсети:

^$|([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])
((/([01]?\\d\\d?|2[0-4]\\d|25[0-5]))?)$
1 голос
/ 23 ноября 2018

Приведенные выше ответы действительны, но что делать, если IP-адрес не находится в конце строки и находится между текстом ... Это регулярное выражение будет даже работать на этом.

код: '\b((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.)){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\b'

входной текстовый файл:

ip address 0.0.0.0 asfasf
 sad sa 255.255.255.255 cvjnzx
zxckjzbxk  999.999.999.999 jshbczxcbx
sjaasbfj 192.168.0.1 asdkjaksb
oyo 123241.24121.1234.3423 yo
yo 0000.0000.0000.0000 y
aw1a.21asd2.21ad.21d2
yo 254.254.254.254 y0
172.24.1.210 asfjas
200.200.200.200
000.000.000.000
007.08.09.210
010.10.30.110

вывод текста:

0.0.0.0
255.255.255.255
192.168.0.1
254.254.254.254
172.24.1.210
200.200.200.200
0 голосов
/ 13 декабря 2018

Ниже приведено выражение регулярного выражения для проверки IP-адреса.

^((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]?)$
0 голосов
/ 03 сентября 2018
ip address can be from 0.0.0.0 to 255.255.255.255

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

(0|1)?[0-9][0-9]? - checking value from 0 to 199
2[0-4][0-9]- checking value from 200 to 249
25[0-5]- checking value from 250 to 255
[.] --> represent verify . character 
{3} --> will match exactly 3
$ --> end of string
0 голосов
/ 18 июля 2018

Попробуйте это:

\b(([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-5])\.(2[0-5][0-5]|1[0-9][0-9]|[1-9][0-9]|[1-9]))\b
0 голосов
/ 10 августа 2014
    const char*ipv4_regexp = "\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\."
    "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b";

Я адаптировал регулярное выражение, взятое из библиотеки JGsoft RegexBuddy, для языка C (regcomp / regexec) и обнаружил, что оно работает, но в некоторых ОС, таких как Linux, есть небольшая проблема.Это регулярное выражение принимает адрес ipv4, например 192.168.100.009, где 009 в Linux считается восьмеричным значением, поэтому адрес не тот, который вы думали.Я изменил это регулярное выражение следующим образом:

    const char* ipv4_regex = "\\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
           "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\b";

с использованием этого регулярного выражения теперь 192.168.100.009 не является действительным адресом ipv4, а 192.168.100.9 - в порядке.

Я изменил регулярное выражение дляадрес многоадресной рассылки тоже:

    const char* mcast_ipv4_regex = "\\b(22[4-9]|23[0-9])\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]?)\\."
                        "(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\b";

Я думаю, что вам нужно адаптировать регулярное выражение к языку, который вы используете для разработки своего приложения

Я поместил пример в Java:

    package utility;

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

    public class NetworkUtility {

        private static String ipv4RegExp = "\\b(?:(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d?)\\.){3}(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d?)\\b";

        private static String ipv4MulticastRegExp = "2(?:2[4-9]|3\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d?|0)){3}";

        public NetworkUtility() {

        }

        public static boolean isIpv4Address(String address) {
            Pattern pattern = Pattern.compile(ipv4RegExp);
            Matcher matcher = pattern.matcher(address);

            return matcher.matches();
        }

        public static boolean isIpv4MulticastAddress(String address) {
             Pattern pattern = Pattern.compile(ipv4MulticastRegExp);
             Matcher matcher = pattern.matcher(address);

             return matcher.matches();
        }
    }
0 голосов
/ 09 июня 2018

Самое точное, простое и компактное регулярное выражение IPv4, которое я могу себе представить, это

^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$

Но как насчет производительности / эффективности ... Извините, я не знаю, кого это волнует?

0 голосов
/ 09 марта 2017

Мне показался этот пример очень полезным, кроме того, он допускает различные нотации ipv4.

пример кода с использованием Python:

    def is_valid_ipv4(ip4):
    """Validates IPv4 addresses.
    """
    import re
    pattern = re.compile(r"""
        ^
        (?:
          # Dotted variants:
          (?:
            # Decimal 1-255 (no leading 0's)
            [3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
          |
            0x0*[0-9a-f]{1,2}  # Hexadecimal 0x0 - 0xFF (possible leading 0's)
          |
            0+[1-3]?[0-7]{0,2} # Octal 0 - 0377 (possible leading 0's)
          )
          (?:                  # Repeat 0-3 times, separated by a dot
            \.
            (?:
              [3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
            |
              0x0*[0-9a-f]{1,2}
            |
              0+[1-3]?[0-7]{0,2}
            )
          ){0,3}
        |
          0x0*[0-9a-f]{1,8}    # Hexadecimal notation, 0x0 - 0xffffffff
        |
          0+[0-3]?[0-7]{0,10}  # Octal notation, 0 - 037777777777
        |
          # Decimal notation, 1-4294967295:
          429496729[0-5]|42949672[0-8]\d|4294967[01]\d\d|429496[0-6]\d{3}|
          42949[0-5]\d{4}|4294[0-8]\d{5}|429[0-3]\d{6}|42[0-8]\d{7}|
          4[01]\d{8}|[1-3]\d{0,9}|[4-9]\d{0,8}
        )
        $
    """, re.VERBOSE | re.IGNORECASE)
    return pattern.match(ip4) <> None
...