Проверка адресов 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 числа, или не работают для меня.


person Matthieu Cartier    schedule 12.03.2011    source источник
comment
Не забывайте, что A, A.B и A.B.C являются допустимыми формами IP-адреса, а также A.B.C.D. Шутки в сторону. Попробуйте ping 2130706433 и ping 127.1, чтобы посмеяться.   -  person dty    schedule 12.03.2011
comment
Мой вариант в Интернете regexr.com/39hqf   -  person Enginer    schedule 22.09.2014


Ответы (37)


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

'\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\b'
    ^                                    ^
person Mark Byers    schedule 12.03.2011
comment
похоже, это также подтверждает такие вещи, как 192.168.1.1.1 - person cwd; 15.08.2014
comment
Должно быть: \b((?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:(?<!\.)\b|\.)){4}; т.е. так он заканчивается границей слова, а не концом строки? Кроме того, здесь я пометил группы без захвата, чтобы избежать нежелательных совпадений. NB: Это все еще не учитывает комментарий @dty, поскольку я не знаком с этой формой IP; хотя он прав, что это кажется действительным. - person JohnLBevan; 16.10.2016
comment
Вместо этого вы можете попробовать следующее: ((1? \ D \ d? | 2 [0-4] \ d | 25 [0-5]) \.) {3} (1? \ D \ d? | 2 [0-4] \ d | 25 [0-5]) - person Morg.; 13.01.2017
comment
Это хорошо работает без захвата - \b(?:(?:[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])\b - person Appy; 07.02.2018
comment
Если я хочу добавить маску, то какое решение будет. Как будто у меня IPv4 25[0-5]|2[0-4][0-9]|[01][0-9][0-9]/[0-9], я хочу добавить /, затем Mask. Итак, что я добавлю, чтобы получить маску? Пример: . .__.__ / __. Всего 15 персонажей. - person WhoAmI; 25.05.2018
comment
09.09.09.09 считается действительным IP-адресом? Это также соответствует этому регулярному выражению. Но ping выдает сообщение об ошибке типа ping: cannot resolve 09.09.09.09: Unknown host. Я думаю, что было бы разумно свести сопоставление только к сопоставлению с десятичной точкой. В этой записи обсуждаются основные ошибки в IP. адреса. - person Ruifeng Ma; 29.03.2019
comment
Эта вещь также проверяет такие случаи, как 192.168.1.36.424.3232.1.0.3.0, 192.168.32.1.424, 9999.166.166.166.166, http://192.168.1.41, .....0.....1.2.3.0, weird:10.0.0.0. - person Narendrasingh Sisodia; 18.05.2020
comment
Измените шаблон на ^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(\.|$)){4}\b, чтобы решить проблему с заполнением нулями одиночных цифр. - person Bren; 11.07.2020
comment
Не останавливайтесь на этом, ответ @danail-gabenski ниже предлагает другое регулярное выражение, обрабатывающее больше крайних случаев. - person Mathieu Rollet; 16.11.2020

^((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        # This is an invalid IP address!

Отклонить:

30.168.1.255.1
127.1
192.168.1.256
-1.2.3.4
1.1.1.1.
3...3

Попробуйте в Интернете с помощью модульных тестов: https://www.debuggex.com/r/-EDZOqxTxhiTncN6/1

person Enginer    schedule 22.09.2014
comment
как насчет 3 ... 3 ip адресов? 3 ... 3 принимается с использованием этого регулярного выражения - person Ankur Loriya; 06.10.2014
comment
А что насчет 1.1.1.01? Считается ли это действительным IPv4-адресом? Спасибо. - person odieatla; 09.10.2015
comment
это регулярное выражение 1.1.1.01 считается ДЕЙСТВИТЕЛЬНЫМ адресом IPv4. Модульные онлайн-тесты debuggex.com/r/-EDZOqxTxhiTncN6/1 - person Enginer; 13.10.2015
comment
кстати ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}$ получить тот же результат debuggex.com/r/mz_-0dEm3wseIKqK, довольно аналогично ответу @Mark Byers - person Enginer; 24.03.2016
comment
@PriteshAcharya Здесь отлично работает. - person Kid Diamond; 15.03.2018
comment
@Sllouyssgort ваша более короткая версия не работает. Он распознает 1.1.1.1. (обратите внимание на конечную точку) как действительный IP-адрес. - person Marko; 11.02.2020

Новейшая, кратчайшая, наименее читаемая версия (49 символов)

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

Блоки [0-9] могут быть заменены на \d в двух местах - это делает его немного менее читаемым, но определенно короче.

Еще новее, еще короче, вторая наименее читаемая версия (55 символов)

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

Эта версия ищет случай 250-5, после чего ловко ИЛИ объединяет все возможные варианты 200-249 100-199 10-99. Обратите внимание, что часть |) не является ошибкой, а фактически объединяет последний регистр для диапазона 0–9. Я также пропустил ?: часть группы, не связанной с захватом, так как мы действительно не заботимся о захваченных элементах, они не были бы захвачены в любом случае, если бы у нас изначально не было полного совпадения.

Старая и сокращенная версия (менее читаемая) (63 символа)

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

Старая (читаемая) версия (70 символов)

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

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

Самый старый ответ (115 символов)

^(?:(?: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-адреса, заканчивающегося на .

person Danail Gabenski    schedule 21.04.2016
comment
На сегодняшний день это единственный правильный ответ в этой ветке. Остальные пропускают такие адреса, как 0.0.0.0, или принимают смешанную восьмеричную / десятичную нотацию, например 033.033.33.033, или даже разрешают 999.999.999.999. Как насчет этого регулярного выражения, которое на 10 символов короче этого ответа: (([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]) - person anneb; 03.08.2017
comment
Ой. Вики, похоже, тоже дала правильный ответ. Его ответ был отвергнут, возможно, потому, что он не объяснил, почему его лучше других. Проголосовал и за него. - person anneb; 03.08.2017
comment
эй @anneb да, вы можете немного сократить его с помощью {2}, иначе вы просто измените порядок сопоставления, что тоже нормально. Другая проблема заключается в том, что вам нужны ^ в начале и $ в конце регулярного выражения, чтобы не совпадать с чем-либо, что отклоняется от регулярного выражения. - person Danail Gabenski; 10.08.2017
comment
Что касается ответа @vicky, проблема в том, что он соответствует таким вещам, как ..23.23, т.е. не уверен, почему это [0-9]? вместо [0-9] в его последнем случае. И снова вам нужны ^ и $, иначе строки вроде 2555.100.232.10 проверяются как правильные, так как они соответствуют последним 55 из числа 2555. - person Danail Gabenski; 10.08.2017
comment
Ошибка с моей стороны. Он принимает 192.168, чего не должен. - person Johndelf Miñao; 30.10.2019
comment
@ JohndelfMiñao не знаю, как вы заставили его принять 192.168, потому что нам нужны всего 2 вещи {4}. Я полагаю, вы хотели отредактировать свой комментарий и допустили ошибку? - person Danail Gabenski; 03.11.2019
comment
Нет, я проверяю это снова и снова. Он просто принимает 192.168. - person Johndelf Miñao; 04.11.2019
comment
@ JohndelfMiñao хм, я обычно использую regex101.com для проверки своих регулярных выражений. Если вы вставляете регулярное выражение в верхнее поле, а затем в поле тестовой строки, вы вводите 192.168. затем выберите ECMAScript слева, он не должен выделять его для вас. Если вы введете действительный IP-адрес v4, например 192.168.0.1, он должен его выделить. Дай мне знать. - person Danail Gabenski; 05.11.2019
comment
Это сработало в тесте, но не сработало в моей проверке. В настоящее время я использую регулярное выражение для проверки углов. - person Johndelf Miñao; 06.11.2019
comment
@ JohndelfMiñao не стесняйтесь задавать новый вопрос со своим примером, и, возможно, я или кто-то еще поможет вам разобраться в этом - должно быть довольно легко исправить. - person Danail Gabenski; 08.11.2019
comment
@tinmarino Я отменил ваше редактирование, потому что оно допускало такие вещи, как 192.168.000.1, который не является действительным адресом. Любой, кто хочет отредактировать этот ответ, сначала прокомментируйте здесь, чтобы избежать подобных проблем - я обычно отвечаю довольно быстро. Конечно, всегда ищу более короткое / лучшее решение. - person Danail Gabenski; 25.12.2019
comment
@DanailGabenski (и другие) для памяти, вы решили заменить последний [01]?[0-9][0-9]? на 1[0-9]{2}|[1-9]?[0-9], потому что вам не нравится ведущий 0. Еще раз спасибо! Я сохраню ваше решение в багаже ​​мастера регулярных выражений. - person Tinmarino; 25.12.2019
comment
@tinmarino да, десятичный формат, который стал стандартным для ipv4, хотя официально не принят, пожалуйста, посмотрите на следующем. В частности, пункт 3, где проект был предложен, но срок его действия истек. Вторая причина такой строгости с проверкой заключается в том, что IP-адреса, представленные в пользовательском интерфейсе, с недесятичными числами, такими как 023 вместо 23, заставляют пользователей думать, что это ошибка / баг. Это также приводит к трудностям с проверкой / безопасностью, поскольку 023 необходимо преобразовать в 23, чтобы избежать дублирования и т. Д. Спасибо за попытку улучшить ситуацию! - person Danail Gabenski; 27.12.2019
comment
Вы можете сделать его короче, если вычесть [0-9] для 2[0-4], 1 и более коротких случаев. ^(?:(25[0-5]|(?:2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$ - person Clayton Singh; 29.01.2020
comment
Спасибо, @ClaytonSingh! Я пошел дальше и изменил фактический ответ. Я также удалил предложение о незахватываемых группах, которое, похоже, не влияет на ответ, но делает его немного короче, теперь ответ составляет 48% от его исходной длины. - person Danail Gabenski; 31.01.2020
comment
$ echo 192.168.1.1 | grep -E '^ ((25 [0-5] | (2 [0-4] | 1 [0-9] | [1-9] |) [0-9]) (\. (?! $) | $)) {4} $ '- Не сработало. Ожидается совпадение - person Talespin_Kit; 24.03.2021
comment
@Talespin_Kit попробуйте -P вместо -E, я ориентировался на синтаксис JavaScript, но, похоже, он совместим с PCRE. - person Danail Gabenski; 25.03.2021
comment
В случае команды hostname -I это: hostname -I|perl -ne'print $& if $_=~/((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.|(?=\s)|$)){4}/', похоже, работает - person Darek Adamkiewicz; 09.05.2021
comment
@DanailGabenski красивое Regex! Но он все равно может быть еще короче, если использовать \d вместо [0-9]. - person MMMahdy-PAPION; 08.06.2021
comment
@DanailGabenski Я новичок в REGEX и изучаю ваше решение для регулярных выражений. Я понимаю первую часть вашего ответа, но мне трудно расшифровать вторую часть вашего ответа. Для меня, как новичка, не могли бы вы объяснить (\. (?! $) | $)) {4} $ часть вашего решения «Еще более новая, даже более короткая, вторая наименее читаемая версия»? Я это понимаю \. - это escape-последовательность для точки, которая следует после выражения, указанного в первой части вашего решения. Спасибо - person Arsik36; 01.07.2021
comment
@ Arsik36, привет, я бы порекомендовал подключить регулярное выражение на сайте вроде regex101.com и выбрать синтаксис JavaScript слева, а затем ввести образец IP-адреса в нижнем поле. Теперь, если вы наведете курсор на любую часть регулярного выражения, которое вы вставили в самое верхнее поле, оно должно показать вам, что оно пытается сопоставить в правой части экрана - это цветовая кодировка и все такое. Упомянутая вами часть пытается сопоставить точку в конце, если это не конец строки, ИЛИ сопоставить конец строки без предварительной точки. Это работает, потому что у нас может быть только 1 конец строки, а с {4} нам требуется ровно 4 экземпляра. - person Danail Gabenski; 06.07.2021

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

\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

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

person Valerij    schedule 12.03.2011
comment
Хороший! Я сделал более эффективную модификацию того, что, кажется, работает: "\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$){4}\b - спасибо! - person Matthieu Cartier; 12.03.2011
comment
@MatthieuCartier Ваш эффективный шаблон регулярного выражения не работал у меня, - person R__raki__; 28.09.2016
comment
255.255.255.000 не является действительным IP - person Stéphane GRILLON; 15.11.2018

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

(?!(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}

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

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-адреса в Интернете, не включая общие частные адреса».

person keba    schedule 09.11.2015
comment
Демоверсия больше не доступна. - person Brad Turek; 02.03.2021

Я думаю, что многие люди, читающие этот пост, будут искать более простые регулярные выражения, даже если они соответствуют некоторым технически недействительным 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]+$/

or:

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

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

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

or:

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

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

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

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

Мои тесты для всего этого можно найти в Интернете, здесь.

person Alex Harvey    schedule 02.07.2018

Это немного больше, чем у некоторых, но это то, что я использую для сопоставления адресов 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])$
person Mickstar    schedule 24.12.2017

Вышеуказанные ответы действительны, но что, если 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
person Kushagra Gupta    schedule 23.11.2018
comment
Это было отмечено отрицательно, пока я не проголосовал за него. Я пытался сделать именно это (больше часов, чем я хочу признать). Он не будет захватывать строку с более чем одним точками на строке, но для моего случая использования я могу с этим смириться. Это отличный ответ, нужно больше голосов! - person anastrophe; 05.03.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" и так далее. '' '

person Shruti Lakkihal    schedule 17.03.2019
comment
Добро пожаловать в StackOverflow. Было бы здорово, если бы вы могли потратить несколько слов на то, почему ваш ответ должен решить проблему с OP. Ответы только в виде кода обычно являются плохими ответами, поскольку они не помогают другим программистам понять, что они сделали неправильно. - person Davide Vitali; 17.03.2019
comment
Используйте правильный отступ в коде, чтобы сделать его читабельным для пользователей. - person Syed Mehtab Hassan; 17.03.2019

Для числа от 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

И для списка IPv4 CIDR, например "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”

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

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

person congacon    schedule 16.08.2019
comment
Добро пожаловать в SO, мы ценим ваш вклад! Не могли бы вы рассказать немного о том, что делают разные регулярные выражения (в частности, последнее)? - person B--rian; 16.08.2019

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

(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}
person Vicky    schedule 12.10.2015
comment
В соответствии со стандартом Ethernet IEEE 802.x проверка IP - это диапазон IP-адресов 0.x.x.x. ››› недопустимый IP-адрес. # 1. Диапазон IP-адресов начинается от 1.x.x.x до 126.x.x.x ›››› можно разрешить настройку. # 2. Диапазон IP-адресов 127.x.x.x ›››› не должен быть разрешен - недопустимый IP-адрес. # 3. Диапазон IP от 128.x.x.x до 223.x.x.x ›› можно настроить. лучший способ обработки предлагается ниже: ^ (22 [0-3] | 2 [0-1] [0-9] | [1] [0-9] [0-9]? | [1-9] ] [0-9] | [1-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-4] | 2 [0-4] [0-9] | [01]? [0-9] [0-9]?) $ - person Yogesh Aggarwal; 16.06.2020

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

^$|([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]))?)$
person hsuk    schedule 05.04.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

person snr    schedule 01.06.2018

Я постарался сделать его немного проще и короче.

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

Если вы ищете java / kotlin:

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

Если кто-то хочет знать, как это работает, вот объяснение. Это действительно так просто. Просто попробуйте: p:

 1. ^.....$: '^' is the starting and '$' is the ending.

 2. (): These are called a group. You can think of like "if" condition groups.

 3. |: 'Or' condition - as same as most of the programming languages.

 4. [01]?\d{1,2}: '[01]' indicates one of the number between 0 and 1. '?' means '[01]' is optional. '\d' is for any digit between 0-9 and '{1,2}' indicates the length can be between 1 and 2. So here the number can be 0-199.

 5. 2[0-4]\d: '2' is just plain 2. '[0-4]' means a number between 0 to 4. '\d' is for any digit between 0-9. So here the number can be 200-249.

 6. 25[0-5]: '25' is just plain 25. '[0-5]' means a number between 0 to 5. So here the number can be 250-255.

 7. \.: It's just plan '.'(dot) for separating the numbers.

 8. {3}: It means the exact 3 repetition of the previous group inside '()'.

 9. ([01]?\d{1,2}|2[0-4]\d|25[0-5]): Totally same as point 2-6

Математически это похоже на:

(0-199 OR 200-249 OR 250-255).{Repeat exactly 3 times}(0-199 OR 200-249 OR 250-255)

Итак, как вы обычно видите, это шаблон для IP-адресов. Надеюсь, это поможет немного понять регулярные выражения. :п

person Arhan Ashik    schedule 26.12.2019

Я постарался сделать его немного проще и короче.

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

Если вы ищете java / kotlin:

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

Если кто-то хочет знать, как это работает, вот объяснение. Это действительно так просто. Просто попробуйте: p:

 1. ^.....$: '^' is the starting and '$' is the ending.

 2. (): These are called a group. You can think of like "if" condition groups.

 3. |: 'Or' condition - as same as most of the programming languages.

 4. [01]?\d{1,2}: '[01]' indicates one of the number between 0 and 1. '?' means '[01]' is optional. '\d' is for any digit between 0-9 and '{1,2}' indicates the length can be between 1 and 2. So here the number can be 0-199.

 5. 2[0-4]\d: '2' is just plain 2. '[0-4]' means a number between 0 to 4. '\d' is for any digit between 0-9. So here the number can be 200-249.

 6. 25[0-5]: '25' is just plain 25. '[0-5]' means a number between 0 to 5. So here the number can be 250-255.

 7. \.: It's just plan '.'(dot) for separating the numbers.

 8. {3}: It means the exact 3 repetition of the previous group inside '()'.

 9. ([01]?\d{1,2}|2[0-4]\d|25[0-5]): Totally same as point 2-6

Математически это похоже на:

(0-199 OR 200-249 OR 250-255).{Repeat exactly 3 times}(0-199 OR 200-249 OR 250-255)

Итак, как вы обычно видите, это шаблон для IP-адресов. Надеюсь, это поможет немного понять регулярные выражения. :п

person Arhan Ashik    schedule 26.12.2019

Вот лучший вариант с подключенными проходящими / неудачными IP-адресами

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

Принимает

127.0.0.1
192.168.1.1
192.168.1.255
255.255.255.255
10.1.1.1
0.0.0.0

Отклоняет

1.1.1.01
30.168.1.255.1
127.1
192.168.1.256
-1.2.3.4
1.1.1.1.
3...3
192.168.1.099
person abhijithvijayan    schedule 23.06.2021

    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();
        }
    }
person Fabio Stafforte    schedule 10.08.2014

-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, который соответствует всему адресному пространству (включая широковещательные рассылки и т. Д.) И ничему другому.

person Jonathzen    schedule 21.02.2016

Думаю, этот самый короткий.

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

Я нашел этот образец очень полезным, кроме того, он позволяет использовать разные нотации 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
person internety    schedule 09.03.2017

((\.|^)(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.

person sudistack    schedule 20.07.2017
comment
этот пропускает, например, 127.0.0.1 и 0.0.0.0 - person anneb; 03.08.2017
comment
Согласно спецификации, следует отклонять ведущие нули. - person John Haugeland; 22.10.2017

Находит действительные IP-адреса, если IP-адрес заключен в любой символ, кроме цифр (позади или впереди IP). Создано 4 обратных ссылки: $ + {первая}. $ + {Вторая}. $ + {Третья}. $ + {Четвертая}

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]))

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

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

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
person rda    schedule 13.09.2017

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

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

\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
person iBug    schedule 24.12.2017

^((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


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

person Ram Sharma    schedule 12.04.2018

Я бы использовал 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]
person nowox    schedule 09.06.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)$

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

person fuweichin    schedule 09.06.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
person AAP    schedule 18.07.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]?)$
person Dilip Paudel    schedule 12.12.2018

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

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

Демо

person BabiBN    schedule 18.12.2018

Этот соответствует только действительным 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'

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

Сначала проверьте, что каждый символ в адресе - это цифра или '.'

Затем проверяем, есть ли ровно 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
person Jason Shaffner    schedule 23.05.2019

Я видел очень плохие регулярные выражения на этой странице .. поэтому я пришел со своим:

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

Объяснение:

num-group = (0-9|10-99|100-199|200-249|250-255)
<border> + { <num-group> + <dot-cahracter> }x3 + <num-group> + <border>

Здесь вы можете проверить, как это работает, здесь

person Martin Mlích    schedule 08.08.2019

Действительное регулярное выражение для адреса IPV4 для Java

^((\\d|[1-9]\\d|[0-1]\\d{2}|2[0-4]\\d|25[0-5])[\\.]){3}(\\d|[1-9]\\d|[0-1]\\d{2}|2[0-4]\\d|25[0-5])$
person sanket patel    schedule 25.01.2020

Мой [расширенный] подход → регулярное выражение для IP-адресов, разделенных пробелами:

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

Использует упреждающий просмотр PCRE.

person sZpak    schedule 19.10.2020

Попробуй это

^ (127 | 10). [0-9] {1,3}. [0-9] {1,3}. [0-9] {1,3}

person Alvin567    schedule 30.05.2021

Этот шаблон исключает 52 символа и принимает команды, начинающиеся с нуля.

/^(?:(?:[01]?\d?\d|2[0-4]\d|25[0-5])(?:\.|$)){4}\b$/
person whoisYeshua    schedule 09.06.2021

У меня работает регулярное выражение:
"\<((([1-9]|1[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([1-9]|1[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4]))\>"

person Omid Babaei    schedule 16.10.2016

person    schedule
comment
Это тоже совпадет с 0987654.3.2.1. - person memowe; 26.10.2012