假设有一个IPv4地址,请尝试提取数字和关键标点符号.然后在必要时切片有效结果.验证IP地址也可能是一种更安全的方法.
在Python 3中:
码
import string
import ipaddress
def validate_port(func):
"""Return the results or raise and exception for invalid ports."""
def wrapper(arg):
result = func(arg)
if len(result) == 2 and not result[-1].isdigit():
raise ValueError("Invalid port number.")
return result
return wrapper
@validate_port
def discover_device(device):
"""Return a list of ip and optional port number. Raise exception for invalid ip."""
result = "".join(i for i in device if i in (string.digits +".:")).strip(":").split(":")
try:
ipaddress.ip_address(result[0])
except ValueError as e:
# Numbers in the device name (index 0) or invalid ip
try:
ipaddress.ip_address(result[1])
except IndexError:
raise e
else:
return result[1:]
else:
return result
演示
discover_device("[]")
# ['192.168.222.123']
discover_device("[]")
# ['192.168.222.123', '8075']
discover_device("[]")
# ['192.168.222.123', '8080']
discover_device("[]")
# ValueError: '192.168.222123' does not appear to be an IPv4 or IPv6 address
discover_device("[]")
# ValueError: '192.168.222123' does not appear to be an IPv4 or IPv6 address
discover_device("[]")
# ValueError: Invalid port number.
特征
>对周围的人物不敏感
> IP地址验证(不是IPv6)和异常处理
>防止设备名称中的数字
>验证端口号(可选)
细节
通常,结果是包含ip和可选端口号的列表.但是,如果数字在设备名称中,则结果的第一个索引将包含不需要的数字.以下是结果示例:
# ['192.168.222.123'] ip
# ['192.168.222.123', '8075'] ip, port
# ['192.168.222123'] invalid ip
# ['.34', '192.168.222.123', '8080'] device #, ip, port
# ['192.168.222.123', '80.805'] invalid port
异常处理测试设备名称中的数字并验证第一个或第二个索引中的IP地址.如果未找到,则引发异常.
虽然验证端口号超出了问题的范围,但端口被假定为数字.在validate_port装饰器中添加了一个简单的测试,可以根据需要应用或更新.装饰器屏蔽discover_device()的输出.如果端口不是纯数字,则会引发异常.有关修改限制,请参阅this post.有关Python装饰器的精彩教程,请参阅this blog.
选项
如果不需要验证,则下列代码应该足够,只要“.”设备名称中缺少:
def discover_device(device):
result = "".join(i for i in device if i in (string.digits +".:")).strip(":").split(":")
if "." not in result[0]:
return result[1:]
return result
如果首选非装饰器解决方案,请定义以下函数:
def validate_port(result):
"""Return the results or raise and exception for invalid ports."""
if len(result) == 2 and not result[-1].isdigit():
raise ValueError("Invalid port number.")
return result
现在将discover_device()的返回值传递给后一个函数,即返回validate_port(result [1:])并返回validate_port(result).
关于@coder的建议.