我无法解决正则表达式,我不知道这是什么问题

时间:2019-11-28 18:52:02

标签: python expression ipv4

我正在尝试编写代码以使用正则表达式找出ipv4地址是否正确,而我似乎无法找出问题所在。

import re
pattern=re.compile('([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][0-9]|2[0-4][0-9]|25[0-5])')
ip=['17.255.16.45','255.255.255.255','0.0.0.0','0.14.255.14','2555.2564.0.3','0.3.255']

for i in range (len(ip)):
    if re.search(pattern,ip[i]):
        print(ip[i],'ok')
    else:
        print(ip[i],"nope")

3 个答案:

答案 0 :(得分:0)

我认为问题在于您的\.包含在替换项中,而应始终将其包含在替换项之前。您可以通过将这些选项放在一对括号中来解决此问题。另外,建议对正则表达式使用raw strings以避免转义问题。

import re
pattern=re.compile(r'(([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][0-9]|2[0-4][0-9]|25[0-5])')
ip=['17.255.16.45','255.255.255.255','0.0.0.0','0.14.255.14','2555.2564.0.3','0.3.255']

for i in range (len(ip)):
    if re.search(pattern,ip[i]):
        print(ip[i],'ok')
    else:
        print(ip[i],"nope")

输出:

17.255.16.45 ok
255.255.255.255 ok
0.0.0.0 ok
0.14.255.14 ok
2555.2564.0.3 nope
0.3.255 nope

答案 1 :(得分:0)

我什至不知道出了什么问题,但是一旦我将其重构为 这似乎可行:

import re

ip_num_pat = r"[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]"

pattern = re.compile(r'(?:({0})\.){{3}}({0})'.format(ip_num_pat))
ip_addrs = [
    '17.255.16.45', '255.255.255.255', '0.0.0.0', '0.14.255.14',
    '2555.2564.0.3', '0.3.255']

for ip in ip_addrs:
    if pattern.match(ip):
        print(ip, 'ok')
    else:
        print(ip, 'nope')

通常,通过破坏它们来跟踪这样的事情会更容易 分成更小的部分。我认为最后一块可能是错误的。

此外,请注意,我已将您的代码更改为使用 .match ,而不是.search。 这很关键,因为否则您将匹配01.2.3.4之类的东西。

但是,正如其他人所说,一种更简单的方法如下所示:

ip_addrs = [
    '17.255.16.45', '255.255.255.255', '0.0.0.0', '0.14.255.14',
    '2555.2564.0.3', '0.3.255', '03.1.2.3']

def is_ip(addr):
    try:
        component_strings = addr.split(".")
        if any(i.startswith("0") and i != "0" for i in component_strings):
            raise ValueError("Components cannot start with 0")
        components = [int(i) for i in component_strings]
        if len(components) != 4:
            raise ValueError("Need 4 parts for an IPv4 address")
        if any(not 0 <= i < 256 for i in components):
            raise ValueError("Components should be in range 0, ..., 255")
        return True
    except ValueError:
        return False

for ip in ip_addrs:
    if is_ip(ip):
        print(ip, 'ok')
    else:
        print(ip, 'nope')

答案 2 :(得分:0)

虽然出于教育目的而对正则表达式进行工作可能很有趣,但如果打算将其放入真实代码中,则最好使用Python的ipaddress模块-而不是重新发明轮子。

它是part of Python standard library since Python 3.3,使用它所需要做的就是:

import ipaddress

# The "for ... in range(len(...))" pattern is not really needed in Python
# the native for can walk your sequence elements:
for address in ip:
    try:
       ipaddress.ip_address(address)
    except ValueError:
       print(address, "Nope")
    else:
       print (adress, "ok")

除正则表达式中的细微错误外,明显的优点是它还可以解析IPv6地址(如果不需要,可以在.version属性中检查协议)-{{1 }}上面的调用返回一个对象,该对象免费提供有关IP的大量信息,而无需付出任何额外的努力,包括但不限于:

ip_address