Python 将逗号和连字符按顺序分隔到 lint

Python to separate both comma and hyphen to lint in order wise

下面是文件输出。

IP:10.10.10.1-10.10.10.10

我需要按顺序将 IP 地址发送到列表。我使用了下面的脚本并且它工作正常。

list1 = []
def ipRange(start_ip, end_ip):
   start = list(map(int, start_ip.split(".")))
   end = list(map(int, end_ip.split(".")))
   print end
   temp = start
   ip_range = []
   ip_range.append(start_ip)
   while temp != end:
      start[3] += 1
      for i in (3, 2, 1):
         if temp[i] == 256:
            temp[i] = 0
            temp[i-1] += 1
      ip_range.append(".".join(map(str, temp)))
   print ip_range   
   return ip_range
my_dict = {}
with open("test5.txt") as f:
   for line in f:
      line = line.strip()
      keyin = line.split(":")
      key = keyin[0]
      linecomma = line.split(":")
      items = linecomma[1].split("-")
      values = items[0:]
      my_dict.setdefault(key, []).extend(values)
for k, v in my_dict.iteritems():
   if k == "IP":
      start_ip,end_ip = v[0], v[1]  

现在我的输入文件如下:

IP:10.10.10.11,10.10.10.2-10.10.10.10,10.10.10.13,10.10.10.10.14-10.10.10.16

现在我需要列表 ip_range 如下所示:

['10.10.10.11', '10.10.10.2', '10.10.10.3', '10.10.10.4', '10.10.10.5', '10.10.10.6', '10.10.10.7', '10.10.10.8', '10.10.10.9', '10.10.10.10', '10.10.10.13', '10.10.10.14', '10.10.10.15', '10.10.10.16']

注意:order wise 不是升序也不是降序。它取决于 test5.txt 文件

注意:test5.txt 文件可能有随机输出,上面是一个示例,下面是另外两个示例。

  Example1:
  IP:10.10.10.1-10.10.10.10,10.10.10.20,10.10.10.10.14-10.10.10.16
  Example2:
  IP:10.10.10.1-10.10.10.16

您可以使用 split

ip = 'IP:10.10.10.11,10.10.10.2-10.10.10.10,10.10.10.13,10.10.10.10.14-
ip_address = ip.split('IP:')[-1]
result = []
for item in ip_address.split(','):
    if '-' in item:
        start,end = map(lambda x:int(x.split('.')[-1]),item.split('-'))
        start_ip = '.'.join(item.split('-')[0].split('.')[:-1])
        result += [start_ip+'.'+str(i) for i in range(start,end+1)]
    else:
        result.append(item)

结果

['10.10.10.11', '10.10.10.2', '10.10.10.3', '10.10.10.4', '10.10.10.5', '10.10.10.6', '10.10.10.7', '10.10.10.8', '10.10.10.9', '10.10.10.10', '10.10.10.13', '10.10.10.10.14', '10.10.10.10.15', '10.10.10.10.16']

一种方法是将 IP 地址转换回数字,然后计数,直到使用整个数字范围。这也适用于 10.0.1.250-10.0.2.5

等示例
import socket
import struct

ip_addresses = []

with open("test5.txt") as f_input:
    for line in f_input:
        if line.startswith('IP:'):
            for entry in line.split(':')[1].split(','):
                ip_range = entry.split('-', 1)

                if len(ip_range) == 2:
                    start_ip = struct.unpack('>L', socket.inet_aton(ip_range[0].replace('-', '.')))[0]
                    end_ip = struct.unpack('>L', socket.inet_aton(ip_range[1].replace('-', '.')))[0]

                    while start_ip <= end_ip:
                        ip_addresses.append(socket.inet_ntoa(struct.pack('>L', start_ip)))
                        start_ip += 1
                else:
                    ip_addresses.append(ip_range[0])

print ip_addresses

所以如果 test5.txt 包含:

IP:10.10.10.1-10.10.10.10,10.10.10.20,10.10.10.14-10.10.10.16
IP:10.10.10.1-10.10.10.16
IP:10.0.1.250-10.0.2.5
IP:172.168.1.100,172.168.1.1-172.168.1-10,172.168.1.11-172.168.1-20

您将得到以下输出:

['10.10.10.1', '10.10.10.2', '10.10.10.3', '10.10.10.4', '10.10.10.5', '10.10.10.6', '10.10.10.7', '10.10.10.8', '10.10.10.9', '10.10.10.10', '10.10.10.20', '10.10.10.14', '10.10.10.15', '10.10.10.16', '10.10.10.1', '10.10.10.2', '10.10.10.3', '10.10.10.4', '10.10.10.5', '10.10.10.6', '10.10.10.7', '10.10.10.8', '10.10.10.9', '10.10.10.10', '10.10.10.11', '10.10.10.12', '10.10.10.13', '10.10.10.14', '10.10.10.15', '10.10.10.16', '10.0.1.250', '10.0.1.251', '10.0.1.252', '10.0.1.253', '10.0.1.254', '10.0.1.255', '10.0.2.0', '10.0.2.1', '10.0.2.2', '10.0.2.3', '10.0.2.4', '10.0.2.5', '172.168.1.100', '172.168.1.1', '172.168.1.2', '172.168.1.3', '172.168.1.4', '172.168.1.5', '172.168.1.6', '172.168.1.7', '172.168.1.8', '172.168.1.9', '172.168.1.10', '172.168.1.11', '172.168.1.12', '172.168.1.13', '172.168.1.14', '172.168.1.15', '172.168.1.16', '172.168.1.17', '172.168.1.18', '172.168.1.19', '172.168.1.20']

socket.inet_ntoa() takes an IP address in string format and converts into a binary format. struct.unpack() 采用压缩二进制格式的数字并将其转换为数字,例如0.0.0.1 将转换为 1。然后脚本只需要正常计数直到达到结束数字,每次反转转换以重新创建字符串格式的 IP 地址。

让我们定义两个函数:一个将 IP 地址转换为 32 位整数(实际上是这样),另一个将整数转换为 IP 地址字符串。

def ip_to_int(ip):
    return sum(int(octet) * 256**(i) for i,octet in enumerate(reversed(ip.split('.'))))

def int_to_ip(x):
    ip = []
    for i in range(3,-1,-1):
        octet, x = divmod(x, 256**i)
        ip.append(str(octet))
    return '.'.join(ip)

我们可以使用这些函数将 IP 范围字符串转换为易于迭代的整数范围。如果 10.10.10.250-10.10.11.3 出现,这也有利于处理范围。

if line.startswith('IP:'):
    ip_list = line.strip().replace('IP:','').split(',')
    for ip_range in ip_list:
        ip_ints = [ip_to_int(ip) for ip in ip_range.split('-')]
        ip_addresses.extend([int_to_ip(ip_int) for ip_int in range(ip_ints[0], ip_ints[-1]+1)])

一些测试:

line = 'IP:10.10.10.1-10.10.10.10,10.10.10.20,10.10.10.14-10.10.10.16\n'
# returns:
['10.10.10.1',
 '10.10.10.2',
 '10.10.10.3',
 '10.10.10.4',
 '10.10.10.5',
 '10.10.10.6',
 '10.10.10.7',
 '10.10.10.8',
 '10.10.10.9',
 '10.10.10.10',
 '10.10.10.20',
 '10.10.10.14',
 '10.10.10.15',
 '10.10.10.16']


line = 'IP:10.0.1.250-10.0.2.5\n'
# returns:
['10.0.1.250',
 '10.0.1.251',
 '10.0.1.252',
 '10.0.1.253',
 '10.0.1.254',
 '10.0.1.255',
 '10.0.2.0',
 '10.0.2.1',
 '10.0.2.2',
 '10.0.2.3',
 '10.0.2.4',
 '10.0.2.5']