Perl в Python Regex - PullRequest
       7

Perl в Python Regex

2 голосов
/ 16 июля 2011

Как можно преобразовать это в Python? Регулярное выражение используется для сопоставления адресов ipv4, но есть ли лучший способ сопоставить это?

if ($line =~ m{\s+id\s+(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}),\s+data\s+(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}),\s+Type Transit\s+(\d{1,2})}) {
    $id = "$1.$2.$3.$4";
    $data = "$5.$6.$7.$8";
}

Ответы [ 4 ]

5 голосов
/ 16 июля 2011
match = re.search(r"\s+id\s+(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}),\s+data\s+(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}),\s+Type Transit\s+(\d{1,2})", subject)
if match:
    id   = ".".join(match.group(1,2,3,4))
    data = ".".join(match.group(5,6,7,8))
else:
    # Match attempt failed
2 голосов
/ 16 июля 2011

Является ли regex действительно правильным инструментом для проверки IP-адреса? Вероятно, нет.

Просто разделите строку по точкам и проверьте, что полученные биты являются целыми числами в диапазоне 0-255. Почти наверняка меньше усилий для компьютера, чем анализ строки с помощью регулярного выражения.

В качестве альтернативы попробуйте посмотреть на некоторые ответы на этот вопрос: Как проверить IP-адрес в Python? - существует множество хороших способов проверки IP-адреса, которые не включают регулярное выражение (хотя и сказал, что, по крайней мере, один из ответов на этот вопрос дает довольно полное регулярное выражение для адресов IPv4 и IPv6)

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

1 голос
/ 16 июля 2011

Вот решение, улучшающее регулярное выражение и добавляющее проверку IP-адреса.

import re

match = re.match(r'\s+id\s+((?:\d+\.){3}\d+),\s+data\s+((?:\d+\.){3}\d+),\s+Type Transit\s+(\d{1,2})', line)
if match:
    id, data = match.group(1, 2)
    # Now actually check the IP addresses.
    _i, _d = id.split('.'), data.split('.')
    if (len(_i) != 4 or not all(s.isdigit() and 0 <= int(s) < 256 for s in _i)
    or len(_d) != 4 or not all(s.isdigit() and 0 <= int(s) < 256 for s in _d)):
        # Cancel that, hit an invalid IP address
        del id, data
        match = None
1 голос
/ 16 июля 2011

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

Вы хотите сопоставить строки следующим образом: id XXX.XXX.XXX.XXX, data XXX.XXX.XXX.XXX, Type Transit XX (с переменным пробелом в большинстве мест).

def extract_ip_addresses(line):
    '''
    Extract the 'id' and 'data' IP addresses from lines of the form::

        ' id X.X.X.X, data X.X.X.X, Type Transit X'

    The number following Type Transit must be a number less than 100 but is not returned.
    Whitespace is flexible.
    '''

    try:
        (id_, id), (data_, data), (type_, transit_, type_transit) = [s.split() for s in line.split(',')]
        if not line.startswith(' ') or id_ != 'id' or data_ != 'data' or type_ != 'Type' or transit_ != 'Transit':
            raise ValueError()
    except ValueError:
        raise ValueError("String in wrong format")
    if len(type_transit) > 2 or not type_transit.isdigit():
        raise ValueError("Type Transit is not a one- or two-digit number.")
    _ = id.split('.')
    if len(_) != 4 or not all(c.isdigit() and 0 <= int(c) < 256 for c in _):
        raise ValueError("Invalid IP address for 'id'.")
    _ = data.split('.')
    if len(_) != 4 or not all(c.isdigit() and 0 <= int(c) < 256 for c in _):
        raise ValueError("Invalid IP address for 'data'.")
    return id, data

Пример использования:

ip, data = extract_ip_addresses('  id   123.45.67.89,    data 98.76.54.210,   Type  Transit  53')
ip == '123.45.67.89'
data == '98.76.54.210'

try:
    extract_ip_addresses('id 1234.5.67.89, data 98.76.54.210, Type Transit 12')
except ValueError as e:  # Invalid IP adderess for 'id'
    print 'Failed as expected, %s' % e

Вы также можете return вместо вызова ValueError, в зависимости от того, как вы хотите его использовать. Тогда вы бы проверили, если extract_ip_addresses(line) is None вместо try его.

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