为了账号安全,请及时绑定邮箱和手机立即绑定

从字符串列表中获取子字符串列表,其中子字符串与某个正则表达式匹配

从字符串列表中获取子字符串列表,其中子字符串与某个正则表达式匹配

肥皂起泡泡 2021-07-07 18:39:35
这个问题是针对 Python 3.6+ 的(但也可以为其他读者回答较低的 Python)。我想从匹配正则表达式的每个字符串中提取一个子字符串。说我有以下几点:a = ['v-01-001', 'v-01-002', 'v-02-001', 'v-02-002', 'v-02-003', 'v-03-001']我想要所有匹配的字符串的最后 3 位数字v-02-\d\d\d,即:['001', '002', '003']我天真的尝试:[x[1] for x in list(map(lambda i: re.search(r'v-02-(\d\d\d)', i), a)) if x]你能想出更优雅的东西吗?
查看完整描述

2 回答

?
烙印99

TA贡献1829条经验 获得超13个赞

你可以这样做:


import re


a = ['v-01-001', 'v-01-002', 'v-02-001', 'v-02-002', 'v-02-003', 'v-03-001']

pattern = re.compile('v-02-(\d{3})$')

print([m.group(1) for m in map(pattern.match, a) if m])

输出


['001', '002', '003']

你也可以使用finditer:


print([m.group(1) for ms in map(pattern.finditer, a) for m in ms])

输出


['001', '002', '003']


查看完整回答
反对 回复 2021-07-13
?
萧十郎

TA贡献1815条经验 获得超12个赞

四种方法可以做到这一点。


第一个只是一个常规的 'ole 循环:


li=[]

for s in a:

    m = re.search(r'v-02-(\d\d\d)', s)

    if m:

        li.append(m.group(1))

 # li=['001', '002', '003']

在列表理解中对同一正则表达式的两次调用中的第二次:


>>> [re.search(r'v-02-(\d\d\d)', s).group(1) for s in a if re.search(r'v-02-(\d\d\d)', s)]

['001', '002', '003']

三是使用map:


>>> [m.group(1) for m in map(lambda s: re.search(r'v-02-(\d\d\d)', s), a) if m]

['001', '002', '003']

最后,您可以将列表展平.join,然后使用findall:


>>> re.findall(r'\bv-02-(\d\d\d)\b', '\t'.join(a))

['001', '002', '003']

或者,使用\nand re.Mvs two \b:


>>> re.findall(r'^v-02-(\d\d\d)$', '\n'.join(a), flags=re.M)

['001', '002', '003']

如果我正在编写这段代码,我可能会以相同的顺序编写它。


我想,在旁观者的眼里,什么被认为是更优雅的。我认为最后一个更优雅。


您还可以跳过正则表达式并使用 Python 的字符串方法:


>>> prefix='v-02-'

>>> [e[len(prefix):] for e in filter(lambda s: s.startswith(prefix),a)]

['001', '002', '003']

如果在这种情况下很重要,那可能是最快的。


2019 年 12 月,会有更优雅的选择。根据PEP 572 中的定义,您将能够使用赋值语句,以便您可以在一个步骤中分配匹配项并测试匹配项:


[m.group(1) for s in a if (m:=re.search(r'v-02-(\d\d\d)', s))]


查看完整回答
反对 回复 2021-07-13
  • 2 回答
  • 0 关注
  • 210 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信