我有一个字符串列表,我希望使用正则表达式进行过滤。我有一个解决方案的开端:
lines = ['Some data', 'Data of interest', 'Some data', 'Data of Interest', 'Some data', 'Data of interest']
r = re.compile(r'.*[iI]nterest.*')
relevant_lines = [r.findall(line) for line in lines]
print(relevant_lines)
......几乎有效:
[[], ['Data of interest'], [], ['Data of Interest'], [], ['Data of interest']]
...但是有没有办法只用匹配和没有嵌套列表的行填充结果列表?
编辑 - 是否有比以下更简洁的方法?
[r[0] for r in [r.findall(line) for line in lines] if len(r) > 0]
答案 0 :(得分:2)
只需使用普通循环,并非所有内容都适合列表comp:
r = re.compile(r'.*[iI]nterest.*')
relevant_lines = []
for line in lines:
mtch = r.match(line)
if mtch:
relevant_lines.append(mtch.group())
如果你使用列表comp,生成器表达式和过滤空列表会更好:
relevant_lines = filter(None,(r.findall(line) for line in lines))
或者确实使用匹配进行过滤:
[x.group() for x in filter(None,(r.match(line) for line in lines))]
for python2使用itertools.ifilter。
或者更方便的方法切换itertools.imap的地图并使用python2过滤ifilter
:
[x.group() for x in filter(None, map(r.match, lines))]
您可以使用内部循环的生成器表达式重写您自己的列表comp:
[r[0] for r in (r.findall(line) for line in lines) if r]
如果您不需要列表,请使用生成器表达式并迭代它。
答案 1 :(得分:1)
relevant_lines = [m.group(0) for m in map(r.match, lines) if m is not None]
这是控制台的结果:
>>> import re
>>> lines = ['Some data', 'Data of interest', 'Some data', 'Data of Interest', 'Some data', 'Data of interest']
>>> r = re.compile(r'.*[iI]nterest.*')
>>> relevant_lines = [m.group(0) for m in map(r.match, lines) if m is not None]
>>> relevant_lines
['Data of interest', 'Data of Interest', 'Data of interest']
事情并不复杂。将函数式编程与生成器结合起来非常好。