Как parseIPv6-адрес в строке с использованием Python 3.x [duplicate]

Убедитесь, что вы не закрываете базу данных. Используя db_close () перед запуском вашего запроса:

Если вы используете несколько запросов в скрипте, даже если вы включая другие страницы, содержащие запросы или соединение с базой данных, возможно, что в любом месте вы будете использовать db_close (), который закроет ваше соединение с базой данных, поэтому убедитесь, что вы не делаете эту ошибку в своих сценариях.

112
задан Stefan Lasiewski 2 November 2015 в 22:58
поделиться

22 ответа

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

Я предполагаю, что в какой-то момент вы захотите что-то сделать с этими адресами, так почему бы не просто перейти прямо к источнику и убедиться, что ваша сетевая библиотека поймет адрес? Это лучше, чем просто надеяться, что какое-либо регулярное выражение будет опубликовано здесь, будет соответствовать вашей концепции реализации адреса.

В Java у нас есть InetAddress. В .NET у нас есть IPAddress. В .NET у вас есть TryParse в классе IPAddress , чтобы выполнить этот тест для вас!

bool IsIP6(string addr) {
    IPAddress ip;
    if (IPAddress.TryParse(addr, out ip)) {
        return ip.AddressFamily == AddressFamily.InterNetworkV6;
    }
    else {
        return false;
    }
}
0
ответ дан Frank Krueger 25 August 2018 в 06:36
поделиться

Следующее будет проверять IPv4, IPv6 (полный и сжатый) и IPv6v4 (полный и сжатый) адреса:

'/^(?>(?>([a-f0-9]{1,4})(?>:(?1)){7}|(?!(?:.*[a-f0-9](?>:|$)){8,})((?1)(?>:(?1)){0,6})?::(?2)?)|(?>(?>(?1)(?>:(?1)){5}:|(?!(?:.*[a-f0-9]:){6,})(?3)?::(?>((?1)(?>:(?1)){0,4}):)?)?(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(?>\.(?4)){3}))$/iD'
47
ответ дан 14 revs 25 August 2018 в 06:36
поделиться

Как было сказано выше, другой способ получить аутентификационный синтаксический анализатор представления IPv6 - использовать программирование. Вот тот, который полностью соответствует RFC-4291 и RFC-5952. Я написал этот код в ANSI C (работает с GCC, прошел тесты в Linux - работает с clang, прошел тесты на FreeBSD). Таким образом, он полагается только на стандартную библиотеку ANSI C, поэтому ее можно скомпилировать повсюду (я использовал ее для разбора IPv6 внутри модуля ядра с помощью FreeBSD).

// IPv6 textual representation validating parser fully compliant with RFC-4291 and RFC-5952
// BSD-licensed / Copyright 2015-2017 Alexandre Fenyo

#include <string.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>

typedef enum { false, true } bool;

static const char hexdigits[] = "0123456789abcdef";
static int digit2int(const char digit) {
  return strchr(hexdigits, digit) - hexdigits;
}

// This IPv6 address parser handles any valid textual representation according to RFC-4291 and RFC-5952.
// Other representations will return -1.
//
// note that str input parameter has been modified when the function call returns
//
// parse_ipv6(char *str, struct in6_addr *retaddr)
// parse textual representation of IPv6 addresses
// str:     input arg
// retaddr: output arg
int parse_ipv6(char *str, struct in6_addr *retaddr) {
  bool compressed_field_found = false;
  unsigned char *_retaddr = (unsigned char *) retaddr;
  char *_str = str;
  char *delim;

  bzero((void *) retaddr, sizeof(struct in6_addr));
  if (!strlen(str) || strchr(str, ':') == NULL || (str[0] == ':' && str[1] != ':') ||
      (strlen(str) >= 2 && str[strlen(str) - 1] == ':' && str[strlen(str) - 2] != ':')) return -1;

  // convert transitional to standard textual representation
  if (strchr(str, '.')) {
    int ipv4bytes[4];
    char *curp = strrchr(str, ':');
    if (curp == NULL) return -1;
    char *_curp = ++curp;
    int i;
    for (i = 0; i < 4; i++) {
      char *nextsep = strchr(_curp, '.');
      if (_curp[0] == '0' || (i < 3 && nextsep == NULL) || (i == 3 && nextsep != NULL)) return -1;
      if (nextsep != NULL) *nextsep = 0;
      int j;
      for (j = 0; j < strlen(_curp); j++) if (_curp[j] < '0' || _curp[j] > '9') return -1;
      if (strlen(_curp) > 3) return -1;
      const long val = strtol(_curp, NULL, 10);
      if (val < 0 || val > 255) return -1;
      ipv4bytes[i] = val;
      _curp = nextsep + 1;
    }
    sprintf(curp, "%x%02x:%x%02x", ipv4bytes[0], ipv4bytes[1], ipv4bytes[2], ipv4bytes[3]);
  }

  // parse standard textual representation
  do {
    if ((delim = strchr(_str, ':')) == _str || (delim == NULL && !strlen(_str))) {
      if (delim == str) _str++;
      else if (delim == NULL) return 0;
      else {
        if (compressed_field_found == true) return -1;
        if (delim == str + strlen(str) - 1 && _retaddr != (unsigned char *) (retaddr + 1)) return 0;
        compressed_field_found = true;
        _str++;
        int cnt = 0;
        char *__str;
        for (__str = _str; *__str; ) if (*(__str++) == ':') cnt++;
        unsigned char *__retaddr = - 2 * ++cnt + (unsigned char *) (retaddr + 1);
        if (__retaddr <= _retaddr) return -1;
        _retaddr = __retaddr;
      }
    } else {
      char hexnum[4] = "0000";
      if (delim == NULL) delim = str + strlen(str);
      if (delim - _str > 4) return -1;
      int i;
      for (i = 0; i < delim - _str; i++)
        if (!isxdigit(_str[i])) return -1;
        else hexnum[4 - (delim - _str) + i] = tolower(_str[i]);
      _str = delim + 1;
      *(_retaddr++) = (digit2int(hexnum[0]) << 4) + digit2int(hexnum[1]);
      *(_retaddr++) = (digit2int(hexnum[2]) << 4) + digit2int(hexnum[3]);
    }
  } while (_str < str + strlen(str));
  return 0;
}
0
ответ дан Alexandre Fenyo 25 August 2018 в 06:36
поделиться

В зависимости от ваших потребностей может быть достаточно аппроксимации, например:

[0-9a-f:]+

(например, с помощью простого файла журнала журналов).

1
ответ дан Bill Lipa 25 August 2018 в 06:36
поделиться

Если вы используете Perl try Net :: IPv6Addr

use Net::IPv6Addr;

if( defined Net::IPv6Addr::is_ipv6($ip_address) ){
  print "Looks like an ipv6 address\n";
}

NetAddr :: IP

use NetAddr::IP;

my $obj = NetAddr::IP->new6($ip_address);

Validate :: IP

use Validate::IP qw'is_ipv6';

if( is_ipv6($ip_address) ){
  print "Looks like an ipv6 address\n";
}
3
ответ дан Brad Gilbert 25 August 2018 в 06:36
поделиться

Попробуйте этот маленький однострочный. Он должен соответствовать только несжатым / сжатым IPv6-адресам (нет гибридов IPv4)

/(?!.*::.*::)(?!.*:::.*)(?!:[a-f0-9])((([a-f0-9]{1,4})?[:](?!:)){7}|(?=(.*:[:a-f0-9]{1,4}::|^([:a-f0-9]{1,4})?::))(([a-f0-9]{1,4})?[:]{1,2}){1,6})[a-f0-9]{1,4}/
-1
ответ дан Carlos Velazquez 25 August 2018 в 06:36
поделиться

Трудно найти регулярное выражение, которое работает для всех случаев IPv6. Их, как правило, трудно поддерживать, они не легко читаемы и могут вызвать проблемы с производительностью. Следовательно, я хочу поделиться альтернативным решением, которое я разработал: Регулярное выражение (RegEx) для IPv6 Отдельно от IPv4

Теперь вы можете спросить, что «этот метод находит только IPv6, как я могу найти IPv6 в тексте или файле? " Вот методы для этой проблемы.

Примечание. Если вы не хотите использовать класс IPAddress в .NET, вы также можете заменить его на мой метод . Он также охватывает отображенные IPv4 и специальные случаи, а IPAddress не распространяется.

class IPv6
{
    public List<string> FindIPv6InFile(string filePath)
    {
        Char ch;
        StringBuilder sbIPv6 = new StringBuilder();
        List<string> listIPv6 = new List<string>();
        StreamReader reader = new StreamReader(filePath);
        do
        {
            bool hasColon = false;
            int length = 0;

            do
            {
                ch = (char)reader.Read();

                if (IsEscapeChar(ch))
                    break;

                //Check the first 5 chars, if it has colon, then continue appending to stringbuilder
                if (!hasColon && length < 5)
                {
                    if (ch == ':')
                    {
                        hasColon = true;
                    }
                    sbIPv6.Append(ch.ToString());
                }
                else if (hasColon) //if no colon in first 5 chars, then dont append to stringbuilder
                {
                    sbIPv6.Append(ch.ToString());
                }

                length++;

            } while (!reader.EndOfStream);

            if (hasColon && !listIPv6.Contains(sbIPv6.ToString()) && IsIPv6(sbIPv6.ToString()))
            {
                listIPv6.Add(sbIPv6.ToString());
            }

            sbIPv6.Clear();

        } while (!reader.EndOfStream);
        reader.Close();
        reader.Dispose();

        return listIPv6;
    }

    public List<string> FindIPv6InText(string text)
    {
        StringBuilder sbIPv6 = new StringBuilder();
        List<string> listIPv6 = new List<string>();

        for (int i = 0; i < text.Length; i++)
        {
            bool hasColon = false;
            int length = 0;

            do
            {
                if (IsEscapeChar(text[length + i]))
                    break;

                //Check the first 5 chars, if it has colon, then continue appending to stringbuilder
                if (!hasColon && length < 5)
                {
                    if (text[length + i] == ':')
                    {
                        hasColon = true;
                    }
                    sbIPv6.Append(text[length + i].ToString());
                }
                else if (hasColon) //if no colon in first 5 chars, then dont append to stringbuilder
                {
                    sbIPv6.Append(text[length + i].ToString());
                }

                length++;

            } while (i + length != text.Length);

            if (hasColon && !listIPv6.Contains(sbIPv6.ToString()) && IsIPv6(sbIPv6.ToString()))
            {
                listIPv6.Add(sbIPv6.ToString());
            }

            i += length;
            sbIPv6.Clear();
        }

        return listIPv6;
    }

    bool IsEscapeChar(char ch)
    {
        if (ch != ' ' && ch != '\r' && ch != '\n' && ch!='\t')
        {
            return false;
        }

        return true;
    }

    bool IsIPv6(string maybeIPv6)
    {
        IPAddress ip;
        if (IPAddress.TryParse(maybeIPv6, out ip))
        {
            return ip.AddressFamily == AddressFamily.InterNetworkV6;
        }
        else
        {
            return false;
        }
    }

}
1
ответ дан Community 25 August 2018 в 06:36
поделиться

Простое регулярное выражение, которое будет соответствовать, но я бы не рекомендовал для валидации любого типа:

([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}

Обратите внимание, что это соответствует сжатию в любом месте адреса, хотя оно не будет соответствовать адрес обратной связи :: 1. Я считаю это разумным компромиссом, чтобы поддерживать регулярное выражение.

Я успешно использую это в правилах интеллектуального выбора iTerm2 для четырехзвёздных адресов IPv6.

1
ответ дан David M. Syzdek 25 August 2018 в 06:36
поделиться

Это регулярное выражение будет соответствовать допустимым адресам IPv6 и IPv4 в соответствии с реализацией регулярного выражения GNU C ++ с использованием режима REGULAR EXTENDED:

"^\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][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){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][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){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][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){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][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){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][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:)))(%.+)?\s*$"
7
ответ дан Egor 25 August 2018 в 06:36
поделиться

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

Некоторые дистрибутивы Unix и Mac преобразуют эти сегменты в восьмеричные.

Я предлагаю использовать 25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d как IPv4 сегмент. [/ д2]

-2
ответ дан Jason Plank 25 August 2018 в 06:36
поделиться

Следующее регулярное выражение предназначено только для IPv6. Группа 1 соответствует IP.

(([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4})
1
ответ дан Jitendra Gosavi 25 August 2018 в 06:36
поделиться

Я должен был бы сильно повторить ответ из Фрэнк Крюгер .

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

Существует несколько способов проверить, является ли данная строка действительным адресом IPv6, а совпадение регулярных выражений - только одно решение.

Использовать если вы можете.

Регулярное выражение, предложенное Factor Mystic , длинное и сложное. Это, скорее всего, работает, но вы также должны подумать о том, как вы справитесь, если он неожиданно потерпит неудачу. Пункт, который я пытаюсь сделать здесь, состоит в том, что если вы не можете создать требуемое регулярное выражение самостоятельно, вы не сможете легко его отладить.

Если у вас нет подходящей библиотеки, это может быть лучше написать собственную процедуру проверки IPv6, которая не зависит от регулярных выражений. Если вы его пишете, вы это понимаете, и если вы это понимаете, вы можете добавить комментарии, чтобы объяснить это, чтобы другие могли также понять и впоследствии сохранить его.

Действуйте осторожно при использовании регулярного выражения, функциональность которого вы можете " t объяснить кому-то еще.

9
ответ дан Jon Cram 25 August 2018 в 06:36
поделиться

Просто совмещение локальных координат от начала координат с квадратными скобками. Я знаю, что это не так полно, но в javascript другим было сложно отслеживать проблемы, прежде всего, из-за того, что они не работают, поэтому мне кажется, что мне сейчас нужно. дополнительные капиталы A-F также не нужны.

^\[([0-9a-fA-F]{1,4})(\:{1,2})([0-9a-fA-F]{1,4})(\:{1,2})([0-9a-fA-F]{1,4})(\:{1,2})([0-9a-fA-F]{1,4})(\:{1,2})([0-9a-fA-F]{1,4})\]

Версия Jinnko упрощена и лучше я вижу.

0
ответ дан Master James 25 August 2018 в 06:36
поделиться

Я сгенерировал следующее, используя python и работаю с модулем re. Утверждения с запросом гарантируют, что в адресе появится правильное количество точек или двоеточий. Он не поддерживает IPv4 в нотации IPv6.

pattern = '^(?=\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$)(?:(?:25[0-5]|[12][0-4][0-9]|1[5-9][0-9]|[1-9]?[0-9])\.?){4}$|(?=^(?:[0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}$)(?![^:]*::.+::[^:]*$)(?:(?=.*::.*)|(?=\w+:\w+:\w+:\w+:\w+:\w+:\w+:\w+))(?:(?:^|:)(?:[0-9a-f]{4}|[1-9a-f][0-9a-f]{0,3})){0,8}(?:::(?:[0-9a-f]{1,4}(?:$|:)){0,6})?$'
result = re.match(pattern, ip)
if result: result.group(0)
0
ответ дан Mike Wilmes 25 August 2018 в 06:36
поделиться

Мне не удалось получить ответ @Factor Mystic для работы с регулярными выражениями POSIX, поэтому я написал тот, который работает с регулярными выражениями POSIX и регулярными выражениями PERL.

Он должен соответствовать:

IPv6 Регулярное выражение:

(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))

Для удобства чтения следующее выражение, разделенное по основным пунктам OR, разделяется на отдельные строки:

# IPv6 RegEx
(
([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|          # 1:2:3:4:5:6:7:8
([0-9a-fA-F]{1,4}:){1,7}:|                         # 1::                              1:2:3:4:5:6:7::
([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|         # 1::8             1:2:3:4:5:6::8  1:2:3:4:5:6::8
([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|  # 1::7:8           1:2:3:4:5::7:8  1:2:3:4:5::8
([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|  # 1::6:7:8         1:2:3:4::6:7:8  1:2:3:4::8
([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|  # 1::5:6:7:8       1:2:3::5:6:7:8  1:2:3::8
([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|  # 1::4:5:6:7:8     1:2::4:5:6:7:8  1:2::8
[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|       # 1::3:4:5:6:7:8   1::3:4:5:6:7:8  1::8  
:((:[0-9a-fA-F]{1,4}){1,7}|:)|                     # ::2:3:4:5:6:7:8  ::2:3:4:5:6:7:8 ::8       ::     
fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|     # fe80::7:8%eth0   fe80::7:8%1     (link-local IPv6 addresses with zone index)
::(ffff(:0{1,4}){0,1}:){0,1}
((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}
(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|          # ::255.255.255.255   ::ffff:255.255.255.255  ::ffff:0:255.255.255.255  (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
([0-9a-fA-F]{1,4}:){1,4}:
((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}
(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])           # 2001:db8:3:4::192.0.2.33  64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
)

# IPv4 RegEx
((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])

Чтобы сделать это проще для понимания, pseudo "повторяет вышеупомянутое:

IPV4SEG  = (25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])
IPV4ADDR = (IPV4SEG\.){3,3}IPV4SEG
IPV6SEG  = [0-9a-fA-F]{1,4}
IPV6ADDR = (
           (IPV6SEG:){7,7}IPV6SEG|                # 1:2:3:4:5:6:7:8
           (IPV6SEG:){1,7}:|                      # 1::                                 1:2:3:4:5:6:7::
           (IPV6SEG:){1,6}:IPV6SEG|               # 1::8               1:2:3:4:5:6::8   1:2:3:4:5:6::8
           (IPV6SEG:){1,5}(:IPV6SEG){1,2}|        # 1::7:8             1:2:3:4:5::7:8   1:2:3:4:5::8
           (IPV6SEG:){1,4}(:IPV6SEG){1,3}|        # 1::6:7:8           1:2:3:4::6:7:8   1:2:3:4::8
           (IPV6SEG:){1,3}(:IPV6SEG){1,4}|        # 1::5:6:7:8         1:2:3::5:6:7:8   1:2:3::8
           (IPV6SEG:){1,2}(:IPV6SEG){1,5}|        # 1::4:5:6:7:8       1:2::4:5:6:7:8   1:2::8
           IPV6SEG:((:IPV6SEG){1,6})|             # 1::3:4:5:6:7:8     1::3:4:5:6:7:8   1::8
           :((:IPV6SEG){1,7}|:)|                  # ::2:3:4:5:6:7:8    ::2:3:4:5:6:7:8  ::8       ::       
           fe80:(:IPV6SEG){0,4}%[0-9a-zA-Z]{1,}|  # fe80::7:8%eth0     fe80::7:8%1  (link-local IPv6 addresses with zone index)
           ::(ffff(:0{1,4}){0,1}:){0,1}IPV4ADDR|  # ::255.255.255.255  ::ffff:255.255.255.255  ::ffff:0:255.255.255.255 (IPv4-mapped IPv6 addresses and IPv4-translated addresses)
           (IPV6SEG:){1,4}:IPV4ADDR               # 2001:db8:3:4::192.0.2.33  64:ff9b::192.0.2.33 (IPv4-Embedded IPv6 Address)
           )

Я разместил сценарий в GitHub, который проверяет регулярное выражение: https://gist.github.com/syzdek/6086 792

200
ответ дан Qix 25 August 2018 в 06:36
поделиться

Я не эксперт Ipv6, но я думаю, что с этим можно получить довольно хороший результат:

^([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{1,4}$|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4})$

ответить «это действительный ipv6», он выглядит как нормально для меня , Разбить его по частям ... забудьте об этом. Я пропустил неопределенный (: :), так как нет необходимости иметь «неуказанный адрес» в моей базе данных.

начало: ^([0-9A-Fa-f]{0,4}:){2,7} & lt; - соответствие сжимаемой части, мы можем перевести это как: между 2 и 7 двоеточиями, которые могут иметь heaxadecimal число между ними.

, а затем : [0-9A-Fa-f]{1,4}$ & lt; - шестнадцатеричное число (начало 0 опущено) ИЛИ ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4} & lt; - адрес Ipv4

5
ответ дан Remi Morin 25 August 2018 в 06:36
поделиться

Это также забирает loopback (:: 1) и ipv6-адреса. изменил {} на + и поместил: внутри первой квадратной скобки.

([A-f0-9:]+:+)+[A-f0-9]+

проверен с помощью ifconfig -a output http://regexr.com/

Параметр unix или Mac OSx terminal o возвращает только соответствующий результат (ipv6), включая :: 1

ifconfig -a | egrep -o '([A-f0-9:]+:+)+[A-f0-9]+'

Получить все IP-адреса (IPv4 ИЛИ IPv6) и сопоставить печать по сроку unix OSx

ifconfig -a | egrep -o '([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) | (([A-f0-9:]+:+)+[A-f0-9]+)'
3
ответ дан Rohit Malgaonkar 25 August 2018 в 06:36
поделиться

Regexes для ipv6 может стать очень сложным, если вы рассматриваете адреса со встроенными ipv4 и сжатыми адресами, как вы можете видеть из некоторых из этих ответов.

Java-библиотека с открытым исходным кодом IPAddress будет проверять все стандартные представления IPv6 и IPv4, а также поддерживает длину префикса (и проверку таких). Отказ от ответственности: я являюсь менеджером проекта этой библиотеки.

Пример кода:

        try {
            IPAddressString str = new IPAddressString("::1");
            IPAddress addr = str.toAddress();
            if(addr.isIPv6() || addr.isIPv6Convertible()) {
                IPv6Address ipv6Addr = addr.toIPv6();
            }
            //use address
        } catch(AddressStringException e) {
            //e.getMessage has validation error
        }
0
ответ дан Sean F 25 August 2018 в 06:36
поделиться

Вы можете использовать инструменты ipextract shell , которые я сделал для этой цели. Они основаны на regexp и grep.

Использование:

$ ifconfig | ipextract6
fe80::1%lo0
::1
fe80::7ed1:c3ff:feec:dee1%en0
23
ответ дан the Tin Man 25 August 2018 в 06:36
поделиться

Осторожно! В Java использование InetAddress и связанных с ним классов (Inet4Address, Inet6Address, URL) может включать сетевой трафик! Например. Разрешение DNS (URL.equals, InetAddress из строки!). Этот вызов может занять много времени и блокируется!

Для IPv6 у меня есть что-то вроде этого. Это, конечно, не обрабатывает очень тонкие детали IPv6, так как индексы зоны разрешены только на некоторых классах адресов IPv6. И это регулярное выражение не записывается для группового захвата, это только «совпадение» типа регулярного выражения.

S - сегмент IPv6 = [0-9a-f]{1,4}

I - IPv4 = (?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})

Схема (первая часть соответствует адресам IPv6 с суффиксом IPv4, вторая часть соответствует адресам IPv6, последний patrt для индекса зоны):

(
(
::(S:){0,5}|
S::(S:){0,4}|
(S:){2}:(S:){0,3}|
(S:){3}:(S:){0,2}|
(S:){4}:(S:)?|
(S:){5}:|
(S:){6}
)
I

|

:(:|(:S){1,7})|
S:(:|(:S){1,6})|
(S:){2}(:|(:S){1,5})|
(S:){3}(:|(:S){1,4})|
(S:){4}(:|(:S){1,3})|
(S:){5}(:|(:S){1,2})|
(S:){6}(:|(:S))|
(S:){7}:|
(S:){7}S
)

(?:%[0-9a-z]+)?

И здесь может появляться регулярное выражение (нечувствительность к регистру, окружающая то, что когда-либо понадобилось, например, начало / конец строки и т. д.):

(?:
(?:
::(?:[0-9a-f]{1,4}:){0,5}|
[0-9a-f]{1,4}::(?:[0-9a-f]{1,4}:){0,4}|
(?:[0-9a-f]{1,4}:){2}:(?:[0-9a-f]{1,4}:){0,3}|
(?:[0-9a-f]{1,4}:){3}:(?:[0-9a-f]{1,4}:){0,2}|
(?:[0-9a-f]{1,4}:){4}:(?:[0-9a-f]{1,4}:)?|
(?:[0-9a-f]{1,4}:){5}:|
(?:[0-9a-f]{1,4}:){6}
)
(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})\.){3}
(?:25[0-5]|2[0-4][0-9]|[01]?[0-9]{1,2})|

:(?::|(?::[0-9a-f]{1,4}){1,7})|
[0-9a-f]{1,4}:(?::|(?::[0-9a-f]{1,4}){1,6})|
(?:[0-9a-f]{1,4}:){2}(?::|(?::[0-9a-f]{1,4}){1,5})|
(?:[0-9a-f]{1,4}:){3}(?::|(?::[0-9a-f]{1,4}){1,4})|
(?:[0-9a-f]{1,4}:){4}(?::|(?::[0-9a-f]{1,4}){1,3})|
(?:[0-9a-f]{1,4}:){5}(?::|(?::[0-9a-f]{1,4}){1,2})|
(?:[0-9a-f]{1,4}:){6}(?::|(?::[0-9a-f]{1,4}))|
(?:[0-9a-f]{1,4}:){7}:|
(?:[0-9a-f]{1,4}:){7}[0-9a-f]{1,4}
)

(?:%[0-9a-z]+)?
4
ответ дан user2623580 25 August 2018 в 06:36
поделиться

Для пользователей PHP 5.2+ filter_var отлично работает.

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

$is_ip4address = (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== FALSE);
$is_ip6address = (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== FALSE);
0
ответ дан Wireblue 25 August 2018 в 06:36
поделиться

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

(?=([0-9a-f]+(:[0-9a-f])*)?(?P<wild>::)(?!([0-9a-f]+:)*:))(::)?([0-9a-f]{1,4}:{1,2}){0,6}(?(wild)[0-9a-f]{0,4}|[0-9a-f]{1,4}:[0-9a-f]{1,4})
23
ответ дан the Tin Man 25 August 2018 в 06:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: