Перевірка адрес 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
Аппі

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 приймається за допомогою цього регулярного виразу
Ankur Loriya

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 (та інші) для пам'яті, ви вирішили її замінивши останню [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)

Надано на випадок, якщо хтось інший шукає перевірку „ІР-адрес Інтернету, не включаючи загальні приватні адреси”


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
Це було позначено негативно, поки я не проголосував за нього. Я намагався зробити саме це протягом (більше годин, ніж я хочу визнати). Він не захопить рядок, який має більше однієї крапки-чотирикутника на рядку, але для мого випадку я можу жити з цим. Це відмінна відповідь, їй потрібно більше голосів!
анастрофа

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. Якби ви могли витратити кілька слів на те, чому ваша відповідь повинна вирішити проблему з ОП, було б чудово. Відповіді лише за кодом - це, як правило, погані відповіді, оскільки вони не допомагають колегам-кодерам зрозуміти, що вони зробили неправильно.
Давіде Віталі

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


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”))*)$де С - регулярний вираз, який використовується для відповідності 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 - rian

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}

Відповідно до стандарту EE-мережі 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якщо третя цифра 0 через 5.

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

Витяг з: Бен Форта. "Вивчення регулярних виразів".


Якщо ні один персонаж розшукується на початку IP - адреси , ні в кінці, ^і $метасимволу повинні бути використані, відповідно.

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

Тест, щоб знайти збіги в тексті, https://regex101.com/r/uAP31A/1


1

Я намагався зробити це дещо простішим та коротшим.

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

^ ((\. | ^) (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) $)
суддік

1
Правильно відхиляти провідні нулі, згідно специфікації.
John Haugeland,

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 - дуже складна річ.

Примітка : Відступ та підкладка служать лише для ілюстрації та не існують у реальному 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

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

0

Легкий шлях

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

Демо

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.