将捕获的组放在一行中

ale*_*cxe 11 python regex syntax

有一个已知的"模式"来获取捕获的组值,如果不匹配则有一个空字符串:

match = re.search('regex', 'text')
if match:
    value = match.group(1)
else:
    value = ""
Run Code Online (Sandbox Code Playgroud)

要么:

match = re.search('regex', 'text')
value = match.group(1) if match else ''
Run Code Online (Sandbox Code Playgroud)

有一种简单而pythonic的方法可以在一行中完成吗?

换句话说,如果没有找到捕获组,我可以提供默认值吗?


例如,我需要_key=字符串后面的文本中提取所有字母数字字符(和):

>>> import re
>>> PATTERN = re.compile('key=(\w+)')
>>> def find_text(text):
...     match = PATTERN.search(text)
...     return match.group(1) if match else ''
... 
>>> find_text('foo=bar,key=value,beer=pub')
'value'
>>> find_text('no match here')
''
Run Code Online (Sandbox Code Playgroud)

有可能find_text()成为一个班轮吗?

这只是一个例子,我正在寻找一种通用的方法.

the*_*eye 10

MatchObjects文档引用,

匹配对象的布尔值始终为True.由于match()search()返回None时没有匹配,您可以测试是否有一个简单的if语句匹配:

match = re.search(pattern, string)
if match:
   process(match)
Run Code Online (Sandbox Code Playgroud)

由于没有其他选项,并且当您使用函数时,我想提供此替代方案

def find_text(text, matches = lambda x: x.group(1) if x else ''):
    return matches(PATTERN.search(text))

assert find_text('foo=bar,key=value,beer=pub') == 'value'
assert find_text('no match here') == ''
Run Code Online (Sandbox Code Playgroud)

它是完全相同的,但只有你需要做的检查是默认参数化.

考虑到@ Kevin的解决方案和@ devnull在评论中的建议,你可以做这样的事情

def find_text(text):
    return next((item.group(1) for item in PATTERN.finditer(text)), "")
Run Code Online (Sandbox Code Playgroud)

这利用了以下事实:next接受默认值作为参数返回.但这有在每次迭代时创建生成器表达式的开销.所以,我会坚持第一个版本.

  • @alecxe这真的很漂亮,但如果你要经常检查,创建一个lambda函数可能会非常繁重,但函数参数只被评估一次.所以,这可能有点轻. (2认同)

Cas*_*yte 5

您可以使用该模式,在捕获组中的字符串末尾使用一个空替代项:

>>> re.search(r'((?<=key=)\w+|$)', 'foo=bar,key=value').group(1)
'value'
>>> re.search(r'((?<=key=)\w+|$)', 'no match here').group(1)
''
Run Code Online (Sandbox Code Playgroud)