Регулярные выражения — последовательности символов, которые задают шаблоны, описывающие некоторый набор строк. Они широко используются в различных областях, включая поиск IP-адресов. Регулярные выражения могут значительно упростить поиск, особенно в больших наборах данных.
Зачем нужны регулярные выражения для поиска IP-адресов?
IP-адрес представляет собой уникальный номер, позволяющий идентифицировать компьютеры и устройства в сети. Этот адрес состоит из четырёх блоков, разделённых точками, каждый блок содержит число от 0 до 255. Например, IP-адрес 192.168.0.1 означает, что компьютер находится в локальной сети и имеет адрес `192.168.0.1`. Регулярные выражения позволяют быстро и точно находить IP-адреса в текстах, файлах, базах данных и других источниках данных. Это особенно полезно в веб-разработке, сетевых инфраструктурах, администрировании сетей, а также в задачах безопасности.
IPv4
Для соответствия формату адреса IPv4 необходимо проверить наличие цифр [0-9]{1,3} три раза {3}, разделенных периодами \. и заканчивающихся другой цифрой.
1 | ^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$ |
Это регулярное выражение слишком простое - если вы хотите, чтобы оно было точным, вам нужно проверить, что числа находятся в диапазоне от 0 до 255, а приведенное выше регулярное выражение принимает 444 в любой позиции. Для проверки 250-255 нужно использовать 25[0-5], или любое другое значение 200 - 2[0-4][0-9], или любое значение 100 или меньше - [01]?[0-9][0-9]. Вы хотите проверить, что за ним следует точка \. три раза {3}, а затем один раз без точки.
1 | ^(?:(?: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]?)$ |
IPv6
Адреса IPv6 имеют вид 8 16-битных шестнадцатеричных слов, разделенных символом двоеточия (:). В данном случае мы проверяем 7 слов, за которыми следуют двоеточия, а затем одно, в котором их нет. Если в слове есть ведущие нули, оно может быть усеченным, то есть каждое слово может содержать от 1 до 4 шестнадцатеричных цифр.
1 | ^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$ |
Однако этого недостаточно. Поскольку адреса IPv6 могут стать довольно "многословными", стандарт определяет, что слова, содержащие только нули, могут быть заменены на ::. Это можно сделать только один раз в адресе (в любом случае от 1 до 7 последовательных слов), поскольку в противном случае это будет неопределенным. Это порождает ряд (довольно неприятных) вариаций:
1 2 3 4 5 6 7 8 | ^::(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}$ ^[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}$ ^[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}$ ^(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}$ ^(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}$ ^(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:)?[0-9a-fA-F]{1,4}$ ^(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}::[0-9a-fA-F]{1,4}$ ^(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}::$ |
Теперь, сложив все вместе (используя чередование), получаем:
1 2 3 4 5 6 7 8 9 | ^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$| ^::(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}$| ^[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}$| ^[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}$| ^(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}$| ^(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}$| ^(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:)?[0-9a-fA-F]{1,4}$| ^(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}::[0-9a-fA-F]{1,4}$| ^(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}::$ |
Не забудьте написать это в многострочном режиме и с кучей комментариев, чтобы тот, кому неизбежно поручат выяснить, что это значит, не набросился на вас с тупым предметом.