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


91

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


12
Не забывайте, что A, AB и ABC являются допустимыми формами IP-адреса, а также ABCD серьезно. Попробуйте ping 2130706433и ping 127.1для смеха.
dty

1
Мой вариант онлайн regexr.com/39hqf
Sllouyssgort

Ответы:


98

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

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

26
похоже, это также подтверждает такие вещи, как192.168.1.1.1
cwd

2
Должно быть \b((?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:(?<!\.)\b|\.)){4}:; т.е. так он заканчивается границей слова, а не концом строки? Кроме того, здесь я пометил группы без захвата, чтобы избежать нежелательных совпадений. NB: Это все еще не принимает во внимание комментарий @dty, поскольку я не знаком с этой формой IP; хотя он прав, что это кажется действительным.
JohnLBevan

Вместо этого вы можете попробовать следующее: ((1? \ D \ d? | 2 [0-4] \ d | 25 [0-5]) \.) {3} (1? \ D \ d? | 2 [0-4] \ d | 25 [0-5])
Морг.

Это хорошо работает без захвата -\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
Appy

3
Является ли 09.09.09.09считается действительным IP? Это также соответствует этому регулярному выражению. Но ping выдает сообщение об ошибке вроде ping: cannot resolve 09.09.09.09: Unknown host. Я думаю, что было бы разумно сократить сопоставление только до сопоставления с десятичной точкой. В этой статье обсуждаются основные ошибки в IP-адресах.
Жуйфэн Ма

79
^((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
1.1.1.1.
3...3

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


как насчет IP адреса "3 ... 3"? 3 ... 3 принимается с использованием этого регулярного выражения
Анкур Лория

7
А что насчет 1.1.1.01? Считается ли это действительным адресом IPv4? Спасибо.
odieatla

это регулярное выражение 1.1.1.01 считается ДЕЙСТВИТЕЛЬНЫМ адресом IPv4. Модульные
Sllouyssgort,

кстати ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}$получить тот же результат debuggex.com/r/mz_-0dEm3wseIKqK , очень похожий на ответ @Mark Byers
Sllouyssgort

@PriteshAcharya Здесь отлично работает.
Kid Diamond

35

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


На данный момент это единственный правильный ответ в этой теме. Другие пропускают такие адреса 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])
anneb

1
@tinmarino Я отменил ваше редактирование, потому что оно разрешало такие вещи, как 192.168.000.1, который не является действительным адресом. Любой, кто хочет отредактировать этот ответ, сначала прокомментируйте здесь, чтобы избежать подобных проблем - я обычно отвечаю довольно быстро. Конечно, всегда ищу более короткое / лучшее решение.
Данаил Габенски

1
@DanailGabenski (и другие) для памяти, вы решили заменить last [01]?[0-9][0-9]?на, 1[0-9]{2}|[1-9]?[0-9]потому что вам не нравится ведущий 0 . Еще раз спасибо! Я сохраню ваше решение в багаже ​​мастера регулярных выражений.
Tinmarino

1
@tinmarino да, десятичный формат, который стал стандартом для ipv4, хотя официально не принят, пожалуйста, обратите внимание на следующее . В частности, пункт 3, где проект был предложен, но срок его действия истек. Вторая причина столь строгой проверки заключается в том, что когда IP-адреса представлены в пользовательском интерфейсе с недесятичными числами, такими как 023 вместо 23, пользователи считают, что это ошибка / баг. Это также приводит к трудностям с проверкой / безопасностью, так как 023 необходимо преобразовать в 23, чтобы избежать дублирования и т. Д. Спасибо за попытку улучшить ситуацию!
Данаил Габенски

1
Вы можете сделать его короче факторинга вне [0-9]для 2[0-4], 1и более коротких случаев. ^(?:(25[0-5]|(?:2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$
Клейтон Сингх

12

IPv4-адрес (точный захват) Соответствует 0.0.0.0–255.255.255.255 Используйте это регулярное выражение для точного сопоставления 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

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


2
Ницца! Я сделал более эффективную модификацию того, что, кажется, работает: "\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$){4}\b- спасибо!
Matthieu Cartier,

2
@MatthieuCartier: Ваш эффективный шаблон регулярного выражения не работал у меня,
R__raki__

255.255.255.000 не является действительным IP
Стефан ГРИЛЛОН

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 отдельных строках) Визуализация регулярных выражений

Демо Debuggex

Возможно, он не оптимизирован по скорости, но хорошо работает только при поиске «реальных» интернет-адресов.

Что будет (и должно) потерпеть неудачу:

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


5

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

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


3

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

3

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

1
Это было отмечено отрицательно, пока я не проголосовал за него. Я пытался сделать именно это (больше часов, чем я хочу признать). Он не будет захватывать строку, в которой есть более одного квадрата точек, но для моего случая использования я могу с этим жить. Это отличный ответ, нужно больше голосов!
anastrophe 04

3

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

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


Добро пожаловать в StackOverflow. Было бы здорово, если бы вы могли потратить несколько слов на то, почему ваш ответ должен решить проблему OP. Ответы только в виде кода обычно являются плохими ответами, поскольку они не помогают другим программистам понять, что они сделали неправильно.
Давиде Витали

Используйте правильный отступ в своем коде, чтобы сделать его читаемым для пользователей,
Сайед Мехтаб Хассан


2

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

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

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


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

1

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

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

В соответствии со стандартом Ethernet IEEE 802.x проверка IP - это диапазон IP 0.xxx >>> не должен быть разрешен - недопустимый IP. # 1. Диапазон IP-адресов начинается от 1.xxx до 126.xxx >>>> можно разрешить настраивать. # 2. Диапазон IP 127.xxx >>>> не должен быть разрешен - неверный IP. # 3. Диапазон IP от 128.xxx до 223.xxx >> может быть разрешен для настройки. лучший способ обработки предлагается ниже: ^ (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]?) $
Йогеш Аггарвал

1

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

^$|([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
(((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третьей цифры .05

Давайте начнем с (((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

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

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


1

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

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


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



0

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

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


этот пропускает, например, 127.0.0.1 и 0.0.0.0
anneb 02

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

1
Согласно спецификации, следует отклонять ведущие нули.
Джон

0

Находит действительные 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

0

Адрес 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

0

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


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


0

Я бы использовал 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]

0

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

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

\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
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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.