如何从Python中的一组regexp匹配中提取第一个非空匹配?

如何从Python中的一组regexp匹配中提取第一个非空匹配?,python,regex,Python,Regex,假设我有一个正则表达式a | b | c | d。如果我将其应用于文本“foobar”,我会得到一个匹配对象 >>> compiled = re.compile('(a)|(b)|(c)|(d)') >>> compiled.search('foobar').groups() (None, 'b', None, None) 如何从这里提取“b”?或者一般来说,当动态构建regexp时,如何从未知数量的组中提取第一个匹配项?在这种特定情况下,您应该使用“a |

假设我有一个正则表达式a | b | c | d。如果我将其应用于文本“foobar”,我会得到一个匹配对象

>>> compiled = re.compile('(a)|(b)|(c)|(d)')
>>> compiled.search('foobar').groups()
(None, 'b', None, None)


如何从这里提取“b”?或者一般来说,当动态构建regexp时,如何从未知数量的组中提取第一个匹配项?

在这种特定情况下,您应该使用“a | b | c | d”,这样您就不会得到多个组。嗯,regexp实际上是动态生成的,它恰好是part1 | part2 | | | | parti | | partn。但是谢谢你的评论!把它从|换成|怎么样?如果你能控制这一代人,就改变它。以?:partN的形式返回每一块,仍然对其进行分组,因此您可以构建?:part1 |?:part2 |@SMark:您不能使用正则表达式或字符串替换来解析正则表达式:在这个特定的例子中,你应该使用'a | b | c | d',这样你就不会得到多个组。这个regexp实际上是动态生成的,它恰好是part1 | part2 |……| parti |……| partn。但是谢谢你的评论!把它从|换成|怎么样?如果你能控制这一代人,就改变它。以?:partN的形式返回每一块,仍然对其进行分组,因此您可以构建?:part1 |?:part2 |@SMark:您不能使用正则表达式或字符串替换来解析正则表达式:哇,太难了。为什么Python没有将此作为匹配组的内置方法?似乎每个人都会一次又一次地发明成百上千万次的东西。我正在给Python邮件列表写一封愤怒的信@bodacydo:我不介意NoneType是否有一个名为“coalesce”的staticmethod,但如果您觉得这很困难,您也可以同样轻松地将上面的一行写入函数中。至于为什么没有*耸耸肩*对我来说并不重要,因为它不重要,而且我无法控制改变它这是错误的想法,我们每个人都可以控制开源项目中的任何东西@bodacydo:好吧,让Python的维护人员来完成我的任务需要付出很大的努力,这对我来说不是一个重要的问题,我自己也不想维护它哇,太难了。为什么Python没有将此作为匹配组的内置方法?似乎每个人都会一次又一次地发明成百上千万次的东西。我正在给Python邮件列表写一封愤怒的信@bodacydo:我不介意NoneType是否有一个名为“coalesce”的staticmethod,但如果您觉得这很困难,您也可以同样轻松地将上面的一行写入函数中。至于为什么没有*耸耸肩*对我来说并不重要,因为它不重要,而且我无法控制改变它这是错误的想法,我们每个人都可以控制开源项目中的任何东西@bodacydo:好吧,让Python的维护人员来完成我的任务需要付出很大的努力,这对我来说不是一个重要的问题,我自己也不想维护它请记住,对于空字符串,g=None,它会失败。请记住,对于空字符串,g=None,它会失败。
reduce(lambda x, y : (x, y)[x is None], groups, None)
>>> g = (None, 'b', None, None)
>>> next(x for x in g if x is not None)
'b'

>>> g = (None, None, None)
>>> next((x for x in g if x is not None), "default")  # try this with filter :)
'default'

>>> g = (None, None, None)  # so you know what happens, and what you could catch
>>> next(x for x in g if x is not None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
filter(lambda x : x is not None, groups)[0]
>>> g = (None,'b',None,None)
>>> filter(None,g)
('b',)
>>> h = (None,None,None)
>>> filter(None,h)
()