我需要检查列表中的任何字符串是否与正则表达式匹配.如果有的话,我想继续.我过去总是这样做的方式是使用列表理解,例如:
r = re.compile('.*search.*')
if [line for line in output if r.match(line)]:
do_stuff()
Run Code Online (Sandbox Code Playgroud)
我现在意识到这是非常低效的.如果列表中的第一个项目匹配,我们可以跳过所有其余的比较并继续.我可以改进这个:
r = re.compile('.*search.*')
for line in output:
if r.match(line):
do_stuff()
break
Run Code Online (Sandbox Code Playgroud)
但我想知道是否有更多的pythonic方式来做到这一点.
MrA*_*ley 20
你可以使用内置any():
if any(re.match(line) for line in output):
do_stuff()
Run Code Online (Sandbox Code Playgroud)
any()传入延迟生成器将允许它在第一个匹配时退出,而不必进一步检查迭代.
Xav*_*hot 10
开始Python 3.8,并引进赋值表达式(PEP 572) (:=运营商),我们也可以捕捉一个证人的的any表达时,发现匹配,并直接使用它:
# pattern = re.compile('.*search.*')
# items = ['hello', 'searched', 'world', 'still', 'searching']
if any((match := pattern.match(x)) for x in items):
print(match.group(0))
# 'searched'
Run Code Online (Sandbox Code Playgroud)
对于每个项目,这是:
pattern.match(x))match变量(None或re.Match对象)match作为 any 表达式的一部分 ( None-> False, Match-> True)match是None,则any搜索循环继续match已经捕获了一个组,那么我们退出any被考虑的表达式True并且match变量可以在条件的主体中使用小智 6
鉴于我还不能发表评论,我想对 MrAlexBailey 的回答做一个小的更正,并回答 nat5142 的问题。正确的形式是:
r = re.compile('.*search.*')
if any(r.match(line) for line in output):
do_stuff()
Run Code Online (Sandbox Code Playgroud)
如果你想找到匹配的字符串,你可以这样做:
lines_to_log = [line for line in output if r.match(line)]
Run Code Online (Sandbox Code Playgroud)
此外,如果要在已编译正则表达式列表 r=[r1,r2,...,rn] 中查找与任何已编译正则表达式匹配的所有行,可以使用:
lines_to_log = [line for line in output if any(reg_ex.match(line) for reg_ex in r)]
Run Code Online (Sandbox Code Playgroud)