检查字符串是否与python中的IP地址模式匹配?

Tom*_*ene 35 python

检查字符串是否与某个模式匹配的最快方法是什么?正则表达式是最好的方法吗?

例如,我有一堆字符串,想要检查每一个字符串以查看它们是否是有效的IP地址(在这种情况下有效意味着正确的格式),是使用正则表达式执行此操作的最快方法吗?或者有更快的东西像字符串格式或其他东西.

这样的事情是我到目前为止所做的:

for st in strs:
    if re.match('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', st) != None:
       print 'IP!'
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 74

看起来您正在尝试验证IP地址.正则表达式可能不是最好的工具.

如果您想接受所有有效的IP地址(包括您可能甚至不知道的某些地址都有效),那么您可以使用IPy (源):

from IPy import IP
IP('127.0.0.1')
Run Code Online (Sandbox Code Playgroud)

如果IP地址无效,则会引发异常.

或者你可以使用</update> (来源):

import socket
try:
    socket.inet_aton(addr)
    # legal
except socket.error:
    # Not legal
Run Code Online (Sandbox Code Playgroud)

如果你真的只想将IPv4与4个小数部分匹配,那么你可以在dot上进行拆分并测试每个部分是0到255之间的整数.

def validate_ip(s):
    a = s.split('.')
    if len(a) != 4:
        return False
    for x in a:
        if not x.isdigit():
            return False
        i = int(x)
        if i < 0 or i > 255:
            return False
    return True
Run Code Online (Sandbox Code Playgroud)

请注意,您的正则表达式不会执行此额外检查.它将接受socket作为有效地址.


zak*_*mad 23

如果您使用Python3,则可以使用ipaddress模块http://docs.python.org/py3k/library/ipaddress.html.例:

>>> import ipaddress

>>> ipv6 = "2001:0db8:0a0b:12f0:0000:0000:0000:0001"
>>> ipv4 = "192.168.2.10"
>>> ipv4invalid = "266.255.9.10"
>>> str = "Tay Tay"

>>> ipaddress.ip_address(ipv6)
IPv6Address('2001:db8:a0b:12f0::1')

>>> ipaddress.ip_address(ipv4)
IPv4Address('192.168.2.10')

>>> ipaddress.ip_address(ipv4invalid)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/python3.4/ipaddress.py", line 54, in ip_address
    address)
ValueError: '266.255.9.10' does not appear to be an IPv4 or IPv6 address

>>> ipaddress.ip_address(str)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/usr/lib/python3.4/ipaddress.py", line 54, in ip_address
    address)
ValueError: 'Tay Tay' does not appear to be an IPv4 or IPv6 address
Run Code Online (Sandbox Code Playgroud)


Ale*_*lli 14

我通常是极少数坚持捍卫正则表达式的Python专家之一(他们在Python社区中声名狼借),但这不是其中之一 - 接受(比如说) '333.444.555.666'作为"IP地址"是真的太差了,如果你需要的RE匹配后做更多的检查,多使用稀土的一点是无论如何丢失.所以,我衷心地第二个@Mark的建议:IPy的普遍性和优雅(如果你想要支持IPv6!),字符串操作和int检查,如果你只需要IPv4(但是,请考虑一下这个限制,然后再想一想 - - IPv6的的时间的方式来- )!

def isgoodipv4(s):
    pieces = s.split('.')
    if len(pieces) != 4: return False
    try: return all(0<=int(p)<256 for p in pieces)
    except ValueError: return False
Run Code Online (Sandbox Code Playgroud)

我宁愿这样做而不是一个复杂的RE来匹配0到256之间的数字! - )


小智 10

在 Python 3.6 上,我认为要简单得多,因为已经包含了 ipaddress 模块:

import ipaddress

    def is_ipv4(string):
        try:
            ipaddress.IPv4Network(string)
            return True
        except ValueError:
            return False
Run Code Online (Sandbox Code Playgroud)

  • 我认为最好用“ except ipaddress.AddressValueError:”来捕获实际错误 (2认同)

Ton*_*nen 6

无需重新验证即可再进行一次验证:

def validip(ip):
    return ip.count('.') == 3 and  all(0<=int(num)<256 for num in ip.rstrip().split('.'))

for i in ('123.233.42.12','3234.23.453.353','-2.23.24.234','1.2.3.4'):
    print i,validip(i)
Run Code Online (Sandbox Code Playgroud)