Как я могу сопоставить адреса IPv6 с регулярным выражением Perl? - PullRequest
5 голосов
/ 26 ноября 2009

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

Бит маски достаточно прост, в этом случае:

(?:\/\d{1,3})?$/

Сложная часть - это разные форматы адреса ipv6. Он должен соответствовать :: beef, beef ::, beef :: beef и т. Д.

Обновление: я почти там ..

/^(\:\:([a-f0-9]{1,4}\:){0,6}?[a-f0-9]{0,4}|[a-f0-9]{1,4}(\:[a-f0-9]{1,4}){0,6}?\:\:|[a-f0-9]{1,4}(\:[a-f0-9]{1,4}){1,6}?\:\:([a-f0-9]{1,4}\:){1,6}?[a-f0-9]{1,4})(\/\d{1,3})?$/i

В данном случае я ограничен использованием регулярного выражения perl.

Ответы [ 8 ]

13 голосов
/ 28 ноября 2009

Этот содержит патч для Regexp :: Common, демонстрирующий полное, точное и проверенное регулярное выражение IPv6. Это прямой перевод грамматики IPv6. Regexp :: IPv6 также является точным.

Что еще более важно, он содержит набор тестов. Запуск этого с вашим регулярным выражением показывает, что вы еще далеко. 10 из 19 пропущенных. 1 из 12 ложных срабатываний. IPv6 содержит множество специальных сокращений, благодаря которым очень легко ошибиться.

Лучшее место для чтения того, что входит в IPv6-адрес: RFC 3986 раздел 3.2.2.

10 голосов
/ 26 ноября 2009

Что вы имеете в виду, что вы не можете просто использовать библиотеку? Как насчет модуля? Regexp::IPv6 даст вам то, что вам нужно.

5 голосов
/ 26 ноября 2009

Я не эксперт по IPv6, но, пожалуйста, поверьте мне, когда я скажу вам, что сопоставить (не говоря уже о проверке) адреса IPv6 нелегко с очень простым регулярным выражением, таким как предложенное вами. Есть много сокращений и различных соглашений для объединения адреса с портом, просто чтобы назвать пример. Одним из таких сокращений является то, что вы можете записать 0: 0: 0: 0: 0: 0: 0: 1 как :: 1, но это еще не все. Если вы читаете по-немецки, я бы посоветовал посмотреть слайды выступления Штеффена Ульриха на 11-м семинаре по немецкому Perl.

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

2 голосов
/ 20 апреля 2011

Это в основном работает ...

^([0-9a-fA-F]{0,4}|0)(\:([0-9a-fA-F]{0,4}|0)){7}$

Минусы: :: как и дела, неправильно обработанные

1 голос
/ 14 апреля 2017

вот тот, который работал для всех примеров IPv6, которые мне удалось найти:

/^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((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)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((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)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((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)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((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)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((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)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((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)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((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)){3}))|:)))(%.+)?\s*$/

перед использованием убедитесь, что это одна строка. это было найдено здесь:

https://community.helpsystems.com/forums/intermapper/miscellaneous-topics/5acc4fcf-fa83-e511-80cf-0050568460e4

проверено на всех примерах со страницы вопроса, страницы сообщества и сайта википедии отсюда:

https://en.wikipedia.org/wiki/IPv6

инструмент для проверки используется здесь:

https://regex101.com/

1 голос
/ 22 января 2012

Попробуйте:

/^(((?=(?>.*?(::))(?!.+\3)))\3?|([\dA-F]{1,4}(\3|:(?!$)|$)|\2))(?4){5}((?4){2}|((2[0-4]|1\d|[1-9])?\d|25[0-5])(\.(?7)){3})\z/ai

От: http://home.deds.nl/~aeron/regex/

1 голос
/ 04 апреля 2011

Если вам нужно в perl проверить, является ли строка адресом IPv6, вы можете попробовать это:

if (/(([\da-f]{0,4}:{0,2}){1,8})/i) { print("$1") };
1 голос
/ 26 ноября 2009

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

^([0-9a-fA-F]{4}|0)(\:([0-9a-fA-F]{4}|0)){7}$

С Библиотека регулярных выражений: IPv6-адрес

Вы также должны прочитать это: Регулярное выражение для адресов IPv6

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...