Подтвердить что ты не робот

Проверка адресов IPv4 с регулярным выражением

Я пытался получить эффективное регулярное выражение для проверки 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 чисел, или не работают для меня.

4b9b3361

Ответ 1

У вас уже есть рабочий ответ, но на случай, если вам интересно, что было не так с вашим оригинальным подходом, ответ заключается в том, что вам нужны скобки вокруг вашего чередования, иначе (\.|$) требуется только в том случае, если число меньше 200.

'\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b'
    ^                                    ^

Ответ 2

^((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]?)$

Принять

127.0.0.1
192.168.1.1
192.168.1.255
255.255.255.255
0.0.0.0
1.1.1.01

Отклонить

30.168.1.255.1
127.1
192.168.1.256
-1.2.3.4
3...3

Попробуйте онлайн-тесты: https://www.debuggex.com/r/-EDZOqxTxhiTncN6/1

Ответ 3

Regex не является инструментом для этой работы. Было бы лучше написать синтаксический анализатор, который разделяет четыре числа и проверяет, что они находятся в диапазоне [0,255]. Нефункциональное регулярное выражение уже не читается!

Ответ 4

Новая и улучшенная более короткая версия

^(?:(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])(\.(?!$)|$)){4}$

Он использует отрицательный lookahead (?!), чтобы удалить случай, когда ip может закончиться с .

Старый ответ

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

Я думаю, что это самое точное и строгое регулярное выражение, оно не принимает такие вещи, как 000.021.01.0., как кажется, большинство других ответов здесь и требуют дополнительного регулярного выражения, чтобы отклонить случаи, подобные этому, т.е. начальные числа 0 и ip, который заканчивается символом .

Ответ 5

Адрес IPv4 (точный захват) Соответствует 0.0.0.0 по 255.255.255.255 Используйте это регулярное выражение для соответствия IP-номерам с точностью. Каждый из четырех номеров хранится в группе захвата, поэтому вы можете получить к ним доступ для дальнейшей обработки.

\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

Изменить: эта часть (\.|$) кажется странной

Ответ 6

Я искал что-то похожее для адресов IPv4 - регулярное выражение, которое также мешало проверять часто используемые частные IP-адреса (192.168.xy, 10.xyz, 172.16.xy), поэтому использовал негативные прогнозы для достижения этой цели:

(?!(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.).*)
(?!255\.255\.255\.255)(25[0-5]|2[0-4]\d|[1]\d\d|[1-9]\d|[1-9])
(\.(25[0-5]|2[0-4]\d|[1]\d\d|[1-9]\d|\d)){3}

(Разумеется, они должны быть в одной строке, отформатированы для удобства чтения на 3 отдельных строках) Regular expression visualization

Debuggex Demo

Возможно, он не оптимизирован по скорости, но работает хорошо, когда ищет только "настоящие" интернет-адреса.

Вещи, которые будут (и должны) потерпеть неудачу:

0.1.2.3         (0.0.0.0/8 is reserved for some broadcasts)
10.1.2.3        (10.0.0.0/8 is considered private)
172.16.1.2      (172.16.0.0/12 is considered private)
172.31.1.2      (same as previous, but near the end of that range)
192.168.1.2     (192.168.0.0/16 is considered private)
255.255.255.255 (reserved broadcast is not an IP)
.2.3.4
1.2.3.
1.2.3.256
1.2.256.4
1.256.3.4
256.2.3.4
1.2.3.4.5
1..3.4

IP-адреса, которые будут (и должны) работать:

1.0.1.0         (China)
8.8.8.8         (Google DNS in USA)
100.1.2.3       (USA)
172.15.1.2      (USA)
172.32.1.2      (USA)
192.167.1.2     (Italy)

Предоставляется на случай, если кто-то еще ищет подтверждение "IP-адресов в Интернете, не включая общие частные адреса"

Ответ 7

Это немного больше, чем некоторые, но это то, что я использую для соответствия адресам IPv4. Простой без компромиссов.

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

Ответ 8

Я думаю, что многие люди, читающие этот пост, будут искать более простые регулярные выражения, даже если они соответствуют некоторым технически недопустимым IP-адресам. (И, как отмечалось в другом месте, регулярное выражение, вероятно, в любом случае не является правильным инструментом для правильной проверки IP-адреса.)

Удалите ^ и, где применимо, замените $ на \b, если вы не хотите совпадать с началом/концом строки.

Базовое регулярное выражение (BRE) (проверено на GNU grep, GNU sed и vim):

/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/

Расширенное регулярное выражение (ERE):

/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/

или же:

/^([0-9]+(\.|$)){4}/

Совместимое с Perl регулярное выражение (PCRE) (протестировано на Perl 5.18):

/^\d+\.\d+\.\d+\.\d+$/

или же:

/^(\d+(\.|$)){4}/

Ruby (протестировано на Ruby 2.1):

Хотя предполагается, что это PCRE, Ruby по какой-либо причине допустил использование этого регулярного выражения в Perl 5.18:

/^(\d+[\.$]){4}/

Мои тесты для всего этого онлайн здесь.

Ответ 9

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

Здесь я взял значение 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" и так далее. """

Ответ 10

Мне удалось создать регулярное выражение из всех других ответов.

(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]?)){3}

Ответ 11

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

^$|([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]))?)$

Ответ 12

(((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-адреса:

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

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

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

Начнем с (((25[0-5])|(2[0-4]\d)|(1\d{2})|(\d{1,2}))\.), A набор из четырех вложенных подвыражений, и хорошо смотрите на них в обратном порядке. (\d{1,2}) соответствует любому one- или двузначному номеру или числам от 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

Ответ 13

Приведенные выше ответы действительны, но что делать, если 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

Ответ 14

/^(?:(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(?1)$/m

Ответ 15

Для числа от 0 до 255 я использую это регулярное выражение:

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

Выше регулярное выражение будет соответствовать целому числу от 0 до 255, но не совпадать с 256.

Поэтому для IPv4 я использую это регулярное выражение:

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

Именно в этой структуре: ^(N)((\.(N)){3})$ где N - регулярное выражение, используемое для сопоставления чисел от 0 до 255.
Это регулярное выражение будет соответствовать IP, как показано ниже:

0.0.0.0
192.168.1.2

но не те, что ниже:

10.1.0.256
1.2.3.
127.0.1-2.3

Для IPv4 CIDR (бесклассовой междоменной маршрутизации) я использую это регулярное выражение:

^(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))$

Именно в этой структуре: ^(N)((\.(N)){3})\/M$ где N - регулярное выражение, используемое для сопоставления с числом от 0 до 255, а M - регулярное выражение, используемое для сопоставления с числом от 0 до 32.
Это регулярное выражение будет соответствовать CIDR, как показано ниже:

0.0.0.0/0
192.168.1.2/32

но не те, что ниже:

10.1.0.256/16
1.2.3./24
127.0.0.1/33

И для списка CIDR IPv4, например "10.0.0.0/16", "192.168.1.1/32", я использую это регулярное выражение:

^("(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))")((,([ ]*)("(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))((\.(([0-9])|([1-9][0-9])|(1([0-9]{2}))|(2[0-4][0-9])|(25[0-5]))){3})\/(([0-9])|([12][0-9])|(3[0-2]))"))*)$

Именно в этой структуре: ^('C')((,([ ]*)('C'))*)$ где C - регулярное выражение, используемое для соответствия CIDR (например, 0.0.0.0/0).
Это регулярное выражение будет соответствовать списку CIDR, как показано ниже:

'10.0.0.0/16','192.168.1.2/32', '1.2.3.4/32'

но не те, что ниже:

'10.0.0.0/16' 192.168.1.2/32 '1.2.3.4/32'

Может быть, это может быть короче, но для меня это легко понять, так хорошо я.

Надеюсь, это поможет!

Ответ 16

    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();
        }
    }

Ответ 17

-bash-3.2$ echo "191.191.191.39" | egrep 
  '(^|[^0-9])((2([6-9]|5[0-5]?|[0-4][0-9]?)?|1([0-9][0-9]?)?|[3-9][0-9]?|0)\.{3}
     (2([6-9]|5[0-5]?|[0-4][0-9]?)?|1([0-9][0-9]?)?|[3-9][0-9]?|0)($|[^0-9])'

>> 191.191.191.39

(Это DFA, который соответствует всему пространству addr (включая трансляции и т.д.) больше ничего.

Ответ 18

Я думаю, что этот самый короткий.

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

Ответ 19

Я нашел этот пример очень полезным, кроме того он допускает различные обозначения 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

Ответ 20

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

Это регулярное выражение не будет принимать 08.8.8.8 или 8.08.8.8 или 8.8.08.8 или 8.8.8.08

Ответ 21

Находит допустимые IP-адреса, если IP обернут вокруг любого символа, отличного от цифр (за или перед IP). 4 Созданные обратные ссылки: $+ {first}. $+ {Second}. $+ {Third}. $+ {Вперед}

Find String:
#any valid IP address
(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))
#only valid private IP address RFC1918
(?<IP>(?<![\d])(:?(:?(?<first>10)[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5])))|(:?(?<first>172)[\.](?<second>(:?1[6-9])|(:?2[0-9])|(:?3[0-1])))|(:?(?<first>192)[\.](?<second>168)))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))

Notepad++ Replace String Option 1: Replaces the whole IP (NO Change):
$+{IP}

Notepad++ Replace String Option 2: Replaces the whole IP octect by octect (NO Change)
$+{first}.$+{second}.$+{third}.$+{forth}

Notepad++ Replace String Option 3: Replaces the whole IP octect by octect (replace 3rd octect value with 0)
$+{first}.$+{second}.0.$+{forth}
NOTE: The above will match any valid IP including 255.255.255.255 for example and change it to 255.255.0.255 which is wrong and not very useful of course.

Замена части каждого октета на фактическое значение, однако вы можете создать собственную находку и заменить, что действительно полезно для изменения IP-адресов в текстовых файлах:

for example replace the first octect group of the original Find regex above:
(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))
with
(?<first>10)

and
(?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))
with
(?<second>216)
and you are now matching addresses starting with first octect 192 only

Find on notepad++:
(?<IP>(?<![\d])(?<first>10)[\.](?<second>216)[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))

Вы все равно можете выполнить Replace с использованием групп back-referece тем же способом, что и раньше.

Вы можете получить представление о том, как указано выше:

cat ipv4_validation_test.txt
Full Match:
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0


Partial Match (IP Extraction from line)
30.168.1.0.1
-1.2.3.4
sfds10.216.24.23kgfd
da11.15.112.255adfdsfds
sfds10.216.24.23kgfd


NO Match
1.1.1.01
3...3
127.1.
192.168.1..
192.168.1.256
da11.15.112.2554adfdsfds
da311.15.112.255adfdsfds

С помощью grep вы можете увидеть результаты ниже:

From grep:
grep -oP '(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0
30.168.1.0
1.2.3.4
10.216.24.23
11.15.112.255
10.216.24.23


grep -P '(?<IP>(?<![\d])(?<first>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<second>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
0.0.0.1
12.108.1.34
192.168.1.1
10.249.24.212
10.216.1.212
192.168.1.255
255.255.255.255
0.0.0.0
30.168.1.0.1
-1.2.3.4
sfds10.216.24.23kgfd
da11.15.112.255adfdsfds
sfds10.216.24.23kgfd


#matching ip addresses starting with 10.216
grep -oP '(?<IP>(?<![\d])(?<first>10)[\.](?<second>216)[\.](?<third>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))[\.](?<forth>(:?\d)|(:?[1-9]\d)|(:?1\d{2})|(:?2[0-4]\d)|(:?25[0-5]))(?![\d]))' ipv4_validation_test.txt
10.216.1.212
10.216.24.23
10.216.24.23

Ответ 22

IPv4-адрес - очень сложная вещь.

Примечание. Отступы и подкладка предназначены только для иллюстрации и не существуют в реальном RegEx.

\b(
  ((
    (2(5[0-5]|[0-4][0-9])|1[0-9]{2}|[1-9]?[0-9])
  |
    0[Xx]0*[0-9A-Fa-f]{1,2}
  |
    0+[1-3]?[0-9]{1,2}
  )\.){1,3}
  (
    (2(5[0-5]|[0-4][0-9])|1[0-9]{2}|[1-9]?[0-9])
  |
    0[Xx]0*[0-9A-Fa-f]{1,2}
  |
    0+[1-3]?[0-9]{1,2}
  )
|
  (
    [1-3][0-9]{1,9}
  |
    [1-9][0-9]{,8}
  |
    (4([0-1][0-9]{8}
      |2([0-8][0-9]{7}
        |9([0-3][0-9]{6}
          |4([0-8][0-9]{5}
            |9([0-5][0-9]{4}
              |6([0-6][0-9]{3}
                |7([0-1][0-9]{2}
                  |2([0-8][0-9]{1}
                    |9([0-5]
    ))))))))))
  )
|
  0[Xx]0*[0-9A-Fa-f]{1,8}
|
  0+[1-3]?[0-7]{,10}
)\b

Эти адреса IPv4 проверяются вышеуказанным RegEx.

127.0.0.1
2130706433
0x7F000001
017700000001
0x7F.0.0.01 # Mixed hex/dec/oct
000000000017700000001 # Have as many leading zeros as you want
0x0000000000007F000001 # Same as above
127.1
127.0.1

Отклоняются.

256.0.0.1
192.168.1.099 # 099 is not a valid number
4294967296 # UINT32_MAX + 1
0x100000000
020000000000

Ответ 23

^((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]?))$


Выше будет регулярное выражение для IP-адреса, как: 221.234.000.112 также для 221.234.0.112, 221.24.03.112, 221.234.0.1


Вы можете представить все виды адресов, как указано выше

Ответ 24

Я бы использовал PCRE и ключевое слово define:

/^
 ((?&byte))\.((?&byte))\.((?&byte))\.((?&byte))$
 (?(DEFINE)
     (?<byte>25[0-5]|2[0-4]\d|[01]?\d\d?))
/gmx

Демо: https://regex101.com/r/IB7j48/2

Причина этого состоит в том, чтобы избежать повторения шаблона (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?). Другие решения, такие как приведенные ниже, работают хорошо, но они не охватывают каждую группу, как того требуют многие.

/^((\d+?)(\.|$)){4}/ 

Единственный другой способ иметь 4 группы захвата - повторить шаблон четыре раза:

/^(?<one>\d+)\.(?<two>\d+)\.(?<three>\d+)\.(?<four>\d+)$/

Поэтому захват ipv4 в Perl очень прост

$ echo "Hey this is my IP address 138.131.254.8, bye!" | \
  perl -ne 'print "[$1, $2, $3, $4]" if \
    /\b((?&byte))\.((?&byte))\.((?&byte))\.((?&byte))
     (?(DEFINE)
        \b(?<byte>25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))
    /x'

[138, 131, 254, 8]

Ответ 25

Самое точное, понятное и компактное регулярное выражение 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)$

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

Ответ 26

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

\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

Ответ 27

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

Ответ 28

Ниже приведено выражение регулярного выражения для проверки 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]?)$

Ответ 29

Простой способ

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

демонстрация

Ответ 30

Этот соответствует только действительным IP-адресам (без предопределенных 0, но он будет совпадать с октетами от 0 до 255 независимо от их "функции" [т.е. зарезервирован, частный и т.д.]) И допускает встроенное сопоставление, где могут быть пробелы до и/или после IP или при использовании нотации CIDR.

grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)'

$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '10.0.1.2'
10.0.1.2

$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address 10.0.1.2'
ip address 10.0.1.2

$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address 10.0.1.2 255.255.255.255'
ip address 10.0.1.2 255.255.255.255

$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address 10.0.1.2/32'
ip address 10.0.1.2/32

$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address 10.0.1.2.32'
$

$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< 'ip address10.0.1.2'
$

$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '10.0.1.256'
$

$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '0.0.0.0'
0.0.0.0

$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '255.255.255.255'
255.255.255.255

$ grep -E '(^| )((([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])($| |/)' <<< '255.255.255.256'
$

Конечно, в случаях, когда IP-адрес является встроенным, вы можете использовать опцию grep "-o" и ваши предпочтения триммера пробела, если вам нужен только полный IP-адрес и ничего, кроме IP-адреса.

Для тех из нас, кто использует Python, эквивалент примерно:

>>> ipv4_regex = re.compile(r'(^| )((?:[1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(?:[1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])($| |/)')
>>> ipv4_regex.search('ip address 10.1.2.3/32')
<re.Match object; span=(10, 20), match=' 10.1.2.3/'>

Если вы разборчивы (ленивы), как я, вы, вероятно, предпочтете использовать группировку, чтобы получить весь IP и ничего, кроме IP, или CIDR и ничего, кроме CIDR или какой-либо их комбинации. Мы можем использовать синтаксис (? P) для именования наших групп для более легкой ссылки.

>>> ipv4_regex = re.compile(r'(?:^| )(?P<address>((?:[1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(?:[1-9]?\d|1\d{2}|2[0-4]\d|25[0-5]))(?P<slash>/)?(?(slash)(?P<cidr>[0-9]|[12][0-9]|3[0-2]))(?:$| )')
>>> match = ipv4_regex.search('ip address 10.0.1.2/32')
>>> match.group('address')
'10.0.1.2'
>>> match.group('cidr')
'32'
>>> "".join((match.group('address'), match.group('slash'), match.group('cidr')))
'10.0.1.2/32'

Конечно, есть способы не использовать регулярные выражения. Вот некоторые условия, которые вы могли бы проверить (это не находит inline, просто подтверждает, что переданный адрес действителен).

Первая проверка состоит в том, что каждый символ в адресе является цифрой или символом "."

Далее проверяем, что есть ровно 3 '.'

Следующие две проверки проверяют, что каждый октет находится между 0 и 255.

И последняя проверка состоит в том, что ни к одному октету не добавляется знак "0".

def validate_ipv4_address(address):
    return all(re.match('\.|\d', c) for c in address) \
        and address.count('.') == 3 \
        and all(0 <= int(octet) <= 255 for octet in address.split('.')) \
        and all((len(bin(int(octet))) <= 10 for octet in address.split('.'))) \
        and all(len(octet) == 1 or d[0] != '0' for octet in address.split('.'))


>>> validate_ipv4_address('255.255.255.255')
True
>>> validate_ipv4_address('10.0.0.1')
True
>>> validate_ipv4_address('01.01.01.01')
False
>>> validate_ipv4_address('123.456.789.0')
False
>>> validate_ipv4_address('0.0.0.0')
True
>>> validate_ipv4_address('-1.0.0.0')
False
>>> validate_ipv4_address('1.1.1.')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in validate_ipv4_address
  File "<stdin>", line 4, in <genexpr>
ValueError: invalid literal for int() with base 10: ''
>>> validate_ipv4_address('.1.1.1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in validate_ipv4_address
  File "<stdin>", line 4, in <genexpr>
ValueError: invalid literal for int() with base 10: ''
>>> validate_ipv4_address('1..1.1')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in validate_ipv4_address
  File "<stdin>", line 4, in <genexpr>
ValueError: invalid literal for int() with base 10: ''

(поразрядно, каждый октет должен быть 8 бит или меньше, но перед каждым добавляется '0b')

>>> bin(0)
'0b0'
>>> len(bin(0))
3
>>> bin(255)
'0b11111111'
>>> len(bin(256))
11