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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3462784/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:11:20  来源:igfitidea点击:

check if a string matches an IP address pattern in python?

python

提问by Tommy Morene

What is the fastest way to check if a string matches a certain pattern? Is regex the best way?

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

For example, I have a bunch of strings and want to check each one to see if they are a valid IP address (valid in this case meaning correct format), is the fastest way to do this using regex? Or is there something faster with like string formatting or something.

例如,我有一堆字符串,想检查每个字符串是否是有效的 IP 地址(在这种情况下有效意味着格式正确),这是使用正则表达式执行此操作的最快方法吗?或者有什么更快的东西,比如字符串格式之类的。

Something like this is what I have been doing so far:

到目前为止,我一直在做这样的事情:

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

采纳答案by Mark Byers

update: The original answer bellow is good for 2011, but since 2012, one is likely better using Python's ipaddressstdlib module- besides checking IP validity for IPv4 and IPv6, it can do a lot of other things as well.</update>

更新:下面的原始答案适用于 2011 年,但自 2012 年以来,使用 Python 的ipaddressstdlib 模块可能会更好- 除了检查 IPv4 和 IPv6 的 IP 有效性之外,它还可以做很多其他事情。</update>

It looks like you are trying to validate IP addresses. A regular expression is probably not the best tool for this.

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

If you want to accept all valid IP addresses (including some addresses that you probably didn't even know were valid) then you can use IPy(Source):

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

from IPy import IP
IP('127.0.0.1')

If the IP address is invalid it will throw an exception.

如果 IP 地址无效,它将引发异常。

Or you could use socket(Source):

或者你可以使用socket(Source)

import socket
try:
    socket.inet_aton(addr)
    # legal
except socket.error:
    # Not legal

If you really want to only match IPv4 with 4 decimal parts then you can split on dot and test that each part is an integer between 0 and 255.

如果您真的只想将 IPv4 与 4 个小数部分匹配,那么您可以在点上拆分并测试每个部分是 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

Note that your regular expression doesn't do this extra check. It would accept 999.999.999.999as a valid address.

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

回答by Greg Hewgill

Your regular expression doesn't check for the end of the string, so it would match:

您的正则表达式不会检查字符串的结尾,因此它将匹配:

123.45.67.89abc123boogabooga

To fix this, use:

要解决此问题,请使用:

'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'

(note the $at the end).

(注意$在最后)。

Finally, in Python the usual style is to use is not Noneinstead of != None.

最后,在 Python 中通常的风格是使用is not None而不是!= None.

回答by Matt Williamson

You can make it a little faster by compiling it:

你可以通过编译让它更快一点:

expression = re.compile('^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$')
for st in strs:
    if expression.match(st):
       print 'IP!'

回答by mykhal

you should precompile the regexp, if you use it repeatedly

你应该预编译正则表达式,如果你重复使用它

re_ip = re.compile('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$')
# note the terminating $ to really match only the IPs

then use

然后使用

if re_ip.match(st):
    print '!IP'

but.. is e.g. '111.222.333.444' really the IP?

但是......例如'111.222.333.444'真的是IP吗?

i'd look at netaddror ipaddrlibraries whether they can be used to match IPs

我会查看netaddripaddr库是否可用于匹配 IP

回答by Alex Martelli

I'm normally the one of the very few Python experts who steadfastly defends regular expressions (they have quite a bad reputation in the Python community), but this is not one of those cases -- accepting (say) '333.444.555.666'as an "IP address" is reallybad, and if you need to do more checks after matching the RE, much of the point of using a RE is lost anyway. So, I second @Mark's recommendations heartily: IPyfor generality and elegance (including support of IPv6 if you want!), string operations and int checks if you only need IPv4 (but, think twice about that limitation, and then think one more -- IPv6's time has waycome!-):

我通常是为数不多的坚定捍卫正则表达式的 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

I'd far rather do that than a convoluted RE to match only numbers between 0 and 255!-)

我宁愿这样做,也不愿使用复杂的 RE 只匹配 0 到 255 之间的数字!-)

回答by Jungle Hunter

If you are validating IP address I would suggest the following:

如果您正在验证 IP 地址,我建议您执行以下操作:

import socket

try:
    socket.inet_aton(addr)
    return True
except socket.error:
    return False

If you just want to check if it is in the right format then you would want to do it for all legal bases(not just base 10 numbering).

如果您只想检查它的格式是否正确,那么您可能希望针对所有合法基础(而不仅仅是以 10 为基础的编号)进行检查。

Also, are the IP address IPv4 only (and none are IPv6) then you could just look up what valid address are and use split()(to get individual componentsof the IP) and int()(to type-caste for comparison). A quick reference to valid IPv4 rules is here.

此外,IP 地址是否仅是 IPv4(而没有是 IPv6),那么您可以查找有效地址是什么并使用split()(以获取IP 的各个组成部分)和int()(类型等级以进行比较)。此处为有效 IPv4 规则的快速参考。

回答by Tony Veijalainen

One more validation without re:

无需重新验证的另一项验证:

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)

回答by Barmaley

I cheated and used combination of multiple answers submitted by other people. I think this is pretty clear and straight forward piece of code. ip_validationshould return Trueor False. Also this answer only works for IPv4 addresses

我作弊并使用了其他人提交的多个答案的组合。我认为这是一段非常清晰和直接的代码。ip_validation应该返回TrueFalse。此外,此答案仅适用于 IPv4 地址

import re
ip_match = re.match('^' + '[\.]'.join(['(\d{1,3})']*4) + '$', ip_input)
ip_validate = bool(ip_match)
if ip_validate:
    ip_validate &= all(map(lambda n: 0 <= int(n) <= 255, ip_match.groups())

回答by zakiakhmad

If you use Python3, you can use ipaddressmodule http://docs.python.org/py3k/library/ipaddress.html. Example:

如果您使用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

回答by Prem Anand

Install netaddr package

安装 netaddr 包

sudo pip install netaddr

And then you can do this

然后你可以这样做

>>> from netaddr import valid_ipv4
>>> valid_ipv4('11.1.1.2') 
True
>>> valid_ipv4('11.1.1.a')
False

Also you create a IPAddress object from that string and a lot more ip related operations

您还可以从该字符串创建一个 IPAddress 对象以及更多与 ip 相关的操作

>>> from netaddr import IPAddress
>>> ip = IPAddress('11.1.1.1')
>>> [f for f in dir(ip) if '__' not in f]
['_module', '_set_value', '_value', 'bin', 'bits', 'format', 'info', 'ipv4', 'ipv6', 'is_hostmask', 'is_ipv4_compat', 'is_ipv4_mapped', 'is_link_local', 'is_loopback', 'is_multicast', 'is_netmask', 'is_private', 'is_reserved', 'is_unicast', 'key', 'netmask_bits', 'packed', 'reverse_dns', 'sort_key', 'value', 'version', 'words']