我是Python的新手,我无法理解它。我有一个列表,我想从那里获取输入并将其写入文件中。
p = ['Eth1/1', 'Eth1/5','Eth2/1', 'Eth2/4','Eth101/1/1', 'Eth101/1/2', 'Eth101/1/3','Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3','Eth103/1/1', 'Eth103/1/2', 'Eth103/1/3','Eth103/1/4','Eth104/1/1', 'Eth104/1/2', 'Eth104/1/3','Eth104/1/4']
我正在尝试什么:
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
i = 0
while i < len(p):
start = p[i].split('/')
if (start[0] == 'Eth101'):
i += 3
key = start[0]
i += 1
while i < len(p) and p[i].split('/')[0] == key:
i += 1
end = p[i-1].split('/')
fw2.write('confi ' + start[0] + '/' + start[1] + '-' + end[1] + '\n mode\n')
我正在寻找什么:
abc1.txt应该具有
int Eth1/1
mode
int Eth1/5
mode
int Eth2/1
mode
int Eth 2/4
mode
abc2.txt应该具有:
int Eth101/1/1-3
mode
int Eth102/1/1-3
mode
int Eth103/1/1-4
mode
int Eth104/1/1-4
mode
因此任何在“ /”前有1位数字的Eth(e:g Eth1 / 1或Eth2 / 2 )应放在一个文件abc1.txt中。
任何在“ /”前3位的Eth(e:g Eth101 / 1/1或Eth 102/1/1 )应位于另一个文件abc2.txt和中。 范围,需要将其写为Eth101 / 1 / 1-3,Eth102 / 1 / 1-3等
有什么想法吗?
答案 0 :(得分:0)
我认为您根本不需要正则表达式。您的所有项目均以“ Eth”开头,后跟一个或多个数字。因此,您可以在第一次/
出现之前检查项目的长度,然后将其写入文件。
p = ['Eth1/1', 'Eth1/5','Eth2/1', 'Eth2/4','Eth101/1/1', 'Eth101/1/2', 'Eth101/1/3','Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3','Eth103/1/1', 'Eth103/1/2', 'Eth103/1/3','Eth103/1/4','Eth104/1/1', 'Eth104/1/2', 'Eth104/1/3','Eth104/1/4']
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
fw2.write('int ' + i + '\n mode\n')
我对您的代码进行了一些重构,以发挥with
的作用。这将正确处理最后关闭文件的操作。同样,不必在序列上重复两次,因此都可以一次迭代完成。
如果数据不如所提供的那么干净,则您可能要使用正则表达式。与正则表达式本身无关,通过编写if re.match(r'((Eth\d{1}\/\d{1,2})', "p" )
,您可以证明是否可以在字符串"p"
而非变量p
的值上为给定的正则表达式创建匹配对象。这是因为您在"
周围使用了p
。
因此,这应该适合您的示例。如果您确实需要正则表达式,这将使您找到一个合适的正则表达式来满足您的需求而又没有其他问题的麻烦。
由于它们在范围内,因此需要像Eth101 / 1 / 1-3,Eth102 / 1 / 1-3等那样写
这可以通过首先计算字符串然后将其写入文件中来实现。但这更像是一个单独的问题。
更新
计算正确的网络范围并不是一件容易的事。在这里,我可以向您介绍一种不会改变代码但增加一些功能的方法。这里的技巧是获得一组连接的网络,这些组不会被其编号打断。为此,我复制了consecutive_groups。当然,您也可以执行pip install more-itertools
来获得该功能。而且我将列表转换为准备魔术的字典,然后将字典重新转换为再次列出。肯定有更好的方法,但这至少对您的输入数据有效。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from itertools import groupby
from operator import itemgetter
p = ['Eth1/1', 'Eth1/5', 'Eth2/1', 'Eth2/4', 'Eth101/1/1', 'Eth101/1/2',
'Eth101/1/3', 'Eth102/1/1', 'Eth102/1/2', 'Eth102/1/3', 'Eth103/1/1',
'Eth103/1/2', 'Eth103/1/3', 'Eth103/1/4', 'Eth104/1/1', 'Eth104/1/2',
'Eth104/1/3', 'Eth104/1/4']
def get_network_ranges(networks):
network_ranges = {}
result = []
for network in networks:
parts = network.rpartition("/")
network_ranges.setdefault(parts[0], []).append(int(parts[2]))
for network, ranges in network_ranges.items():
ranges.sort()
for group in consecutive_groups(ranges):
group = list(group)
if len(group) == 1:
result.append(network + "/" + str(group[0]))
else:
result.append(network + "/" + str(group[0]) + "-" +
str(group[-1]))
result.sort() # to get ordered results
return result
def consecutive_groups(iterable, ordering=lambda x: x):
"""taken from more-itertools (latest)"""
for k, g in groupby(
enumerate(iterable), key=lambda x: x[0] - ordering(x[1])
):
yield map(itemgetter(1), g)
# only one line added to do the magic
with open("abc1.txt", "w+") as fw1, open("abc2.txt", "w+") as fw2:
p = get_network_ranges(p)
for i in p:
if len(i.partition("/")[0]) == 4:
fw1.write('int ' + i + '\n mode\n')
else:
fw2.write('int ' + i + '\n mode\n')