我希望能够将“10. [3-25] .0.X”之类的东西解析为此规则描述的实际IP地址列表,因此对于上面的示例规则,列表将是[10.3。 0.0,10.3.0.1 .... 10.25.0.255]。最好的方法是什么? 到目前为止,我唯一能够提出的是以下看起来很糟糕的功能:
wc = ''.join(wc.split()).upper()
wc = re.sub(r'(?<![\[-])(\d+)(?![\]-])', r'[\1-\1]', wc)
wc = re.sub(r'X', r'[0-255]', wc).split('.')
ips = []
for i in range(int(re.findall(r'(\d+)-(\d+)', wc[0])[0][0]), int(re.findall(r'(\d+)-(\d+)', wc[0])[0][1]) + 1):
for j in range(int(re.findall(r'(\d+)-(\d+)', wc[1])[0][0]), int(re.findall(r'(\d+)-(\d+)', wc[1])[0][1]) + 1):
for k in range(int(re.findall(r'(\d+)-(\d+)', wc[2])[0][0]), int(re.findall(r'(\d+)-(\d+)', wc[2])[0][1]) + 1):
for p in range(int(re.findall(r'(\d+)-(\d+)', wc[3])[0][0]), int(re.findall(r'(\d+)-(\d+)', wc[3])[0][1]) + 1):
ips.append(str(i) + '.' + str(j) + '.' + str(k) + '.' + str(p))
return ips
任何改进的想法都将受到高度赞赏。
答案 0 :(得分:1)
Here's使用itertools.product
的可能示例。我们的想法是首先用八位字节评估“模板”(例如1.5.123.2-5,23.10-20.X.12,...)八位字节(每个产生一个值列表),然后取这些列表的笛卡尔积
import itertools
import re
import sys
def octet(s):
"""
Takes a string which represents a single octet template.
Returns a list of values. Basic sanity checks.
"""
if s == 'X':
return xrange(256)
try:
low, high = [int(val) for val in s.strip('[]').split('-')]
if low > high or low < 0 or high > 255:
raise RuntimeError('That is no valid range.')
return xrange(low, high + 1)
except ValueError as err:
number = int(s)
if not 0 <= number <= 255:
raise ValueError('Only 0-255 allowed.')
return [number]
if __name__ == '__main__':
try:
template = sys.argv[1]
octets = [octet(s) for s in template.split('.')]
for parts in itertools.product(*octets):
print('.'.join(map(str, parts)))
except IndexError as err:
print('Usage: %s IP-TEMPLATE' % (sys.argv[0]))
sys.exit(1)
(小)例子:
$ python ipregex.py '1.5.123.[2-5]'
1.5.123.2
1.5.123.3
1.5.123.4
1.5.123.5
$ python ipregex.py '23.[19-20].[200-240].X'
23.19.200.0
23.19.200.1
23.19.200.2
...
23.20.240.253
23.20.240.254
23.20.240.255
答案 1 :(得分:1)
你可以让这更简单。
首先,不要四次写完全相同的东西,而是使用循环或listcomp:
ranges = [range(int(re.findall(r'(\d+)-(\d+)', wc[i])[0][0]),
int(re.findall(r'(\d+)-(\d+)', wc[i])[0][1]) + 1)
for i in range(4)]
您还可以将嵌套循环转换为笛卡尔积的平坦循环:
for i, j, k, p in itertools.product(*ranges):
你可以把那个长串连接混乱变成一个简单的格式或加入呼叫:
ips.append('{}.{}.{}.{}'.format(i, j, k, p)) # OR
ips.append('.'.join(map(str, (i, j, k, p))))
这意味着您不需要首先拆分4个组件:
for components in itertools.product(*ranges):
ips.append('{}.{}.{}.{}'.format(*components)) # OR
ips.append('.'.join(map(str, components)))
现在循环非常简单,你可以把它变成listcomp:
ips = ['{}.{}.{}.{}'.format(*components)
for components in itertools.product(*ranges)]
答案 2 :(得分:-1)
ip = re.search(r'(\ d {1,3}。){3} \ d {1,3}','192.168.1.100') 打印(ip.group())
o / p ==> 192.168.1.100
情况:2 ips = re.findall(r'(\ d {1,3}。){3} \ d {1,3}','192.168.1.100') 打印(ips)
o / p ==> ['1。']
情况:3 ips = re.findall(r'(?:\ d {1,3}。){3} \ d {1,3}','192.168.1.100') 打印(ips)
o / p ==> ['192.168.1.100']
为什么case1(search)的re不适用于case2(findall)