问题
背景:
我有一个包含10,000个列表的列表,其中包含需要转换为特定格式的不规则数据。这些数据在转换后将被摄入到熊猫的数据中。
TL/DR;如何优雅地转换列表中以下正则表达式的匹配字符串?
Regex‘d{1,3}-\d{1,3},d{1,3}-\d{1,3}’
示例: '1-3,6-8‘到'1 2 3 6 7’
当前解决方案:使用列表理解的需要多个类型的转换来转换字符串,并且不适合作为持久的解决方案。
pat = re.compile('\d{1,3}-\d{1,3},\d{1,3}-\d{1,3}')
row = ['sss-www,ddd-eee', '1-3,6-8', 'XXXX', '0-2,3-7','234','1,5']
lst = [((str(list(range(int(x.split(',')[0].split('-')[0]),
int(x.split(','[0].split('-')[1])+1))).strip('[]').replace(',', '')+' '
+str(list(range(int(x.split(',')[1].split('-')[0]),
int(x.split(',')[1].split('-')[1]) + 1))).strip('[]').replace(',', '')))
if pat.match(str(x)) else x for x in row]结果
['sss-www,ddd-eee', '1 2 3 6 7 8', 'XXXX', '0 1 2 3 4 5 6 7', '234', '1,5']发布于 2016-11-05 17:08:40
抓捕小组就更容易了。
然后将组列表转换为整数,并在一个与itertools.chain链接的列表理解中对它们进行2乘2的处理。
import re,itertools
pat = re.compile('(\d{1,3})-(\d{1,3}),(\d{1,3})-(\d{1,3})')
z='1-3,6-8'
groups = [int(x) for x in pat.match(z).groups()]
print(list(itertools.chain(*(list(range(groups[i],groups[i+1]+1)) for i in range(0,len(groups),2)))))结果:
[1, 2, 3, 6, 7, 8]不过,你不确定那是“优雅”。它仍然很复杂,主要是因为大多数对象返回需要显式转换为list的生成器。
发布于 2016-11-05 17:15:41
有几种方法可以做到这一点,以下是我的方法:
import re
txt = '1-3,6-8'
# Safer to use a raw string
pat = re.compile(r'(\d{1,3})-(\d{1,3}),(\d{1,3})-(\d{1,3})')
m = pat.match(txt)
if m:
start1, end1, start2, end2 = m.groups()
result = [i for i in range(int(start1), int(end1)+1)]
result += [i for i in range(int(start2), int(end2)+1)]
print(result)给予:
[1, 2, 3, 6, 7, 8]我在这里假设Python 3(如问题中所述)。
Python 2可以使用:
result = range(int(start1), int(end1)+1)
result += range(int(start2), int(end2)+1)发布于 2016-11-05 17:26:06
我想你也想处理更长的序列,比如1-10,15,23-25?您实际上不需要正则表达式,常规字符串处理函数将很好地工作。
def parse_sequence(seq):
result = []
for part in seq.split(','):
points = [int(s) for s in part.split('-')]
if len(points) == 2:
result.extend(range(points[0], points[1]+1))
elif len(points) == 1:
result.append(points[0])
else:
raise ValueError('invalid sequence')
return resulthttps://stackoverflow.com/questions/40440873
复制相似问题