Python 如果列表中的任何字符串与regex匹配

Python 如果列表中的任何字符串与regex匹配,python,regex,Python,Regex,我需要检查列表中的任何字符串是否与正则表达式匹配。如果有的话,我想继续。我过去一直使用的方法是将列表理解与以下内容结合使用: r = re.compile('.*search.*') if [line for line in output if r.match(line)]: do_stuff() 我现在意识到这是相当低效的。如果列表中的第一项匹配,我们可以跳过所有其他比较,继续。我可以通过以下方式来改进这一点: r = re.compile('.*search.*') for line

我需要检查列表中的任何字符串是否与正则表达式匹配。如果有的话,我想继续。我过去一直使用的方法是将列表理解与以下内容结合使用:

r = re.compile('.*search.*')
if [line for line in output if r.match(line)]:
  do_stuff()
我现在意识到这是相当低效的。如果列表中的第一项匹配,我们可以跳过所有其他比较,继续。我可以通过以下方式来改进这一点:

r = re.compile('.*search.*')
for line in output:
  if r.match(line):
    do_stuff()
    break

但是我想知道是否有一种更具python风格的方法可以做到这一点。

您可以使用内置的
any()


将惰性生成器传递到
any()
将允许它在第一次匹配时退出,而无需进一步检查iterable。

鉴于我还不允许评论,我想对MrAlexBailey的答案进行一点更正,并回答nat5142的问题。正确的形式是:

r = re.compile('.*search.*')
if any(r.match(line) for line in output):
    do_stuff()
如果要查找匹配的字符串,请执行以下操作:

lines_to_log = [line for line in output if r.match(line)]
此外,如果要在已编译正则表达式列表r=[r1,r2,…,rn]中查找与任何已编译正则表达式匹配的所有行,可以使用:

lines_to_log = [line for line in output if any(reg_ex.match(line) for reg_ex in r)]

Python 3.8
开始,并引入(
:=
运算符),我们还可以在找到匹配项时捕获
任何
表达式的见证,并直接使用它:

# 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'
对于每个项目,这是:

  • 应用正则表达式搜索(
    pattern.match(x)
  • 将结果分配给
    match
    变量(要么
    None
    要么
    re.match
    对象)
  • match
    的真值作为任何表达式的一部分应用(
    None
    ->
    False
    match
    ->
    True
  • 如果
    match
    None
    ,则
    any
    搜索循环继续
  • 如果
    match
    捕获了一个组,那么我们将退出
    任何被认为
    True
    的表达式,并且
    match
    变量可以在条件体内使用

在@MrAlexBailey给出的回答中,回答@nat5142提出的问题:
“有没有办法使用此方法访问匹配的字符串?我想打印它以用于日志记录”,假设“this”意味着:

if any(re.match(line) for line in output):
    do_stuff()
你可以在发电机上做一个for循环

# r = re.compile('.*search.*')
for match in [line for line in output if r.match(line)]:
    do_stuff(match) # <- using the matched object here
虽然这不涉及“任何”功能,甚至可能不接近您想要的功能

我认为这个答案不太相关,所以这是我的第二次尝试。。。 我想你可以这样做:

# def log_match(match):
#    if match: print(match)
#    return match  
if any(log_match(re.match(line)) for line in output):
    do_stuff()

为什么不使用内置的
any()
?例如:
if any(为输出中的行重新匹配(行)
@Jkdc becasue
any()
获取一个列表并将每个元素转换为一个
bool
,然后计算bool。因此,为了让它变得有用,我仍然必须对每个元素进行正则表达式匹配。@ewok:no,
any
需要一些可移植的东西。jkdc的代码使用惰性生成器表达式,而不是列表。@DSM。懒发电机就是我要找的。除了使用
any
之外,我认为您刚刚用第二次尝试回答了您的问题。是否有任何方法可以使用此方法访问匹配的字符串?我想打印它用于日志记录,而不是
re.match
它不应该是
r.match
,因为OP已经创建了一个编译的正则表达式对象
r=re.compile('.*search.*')
# r = re.compile('.*search.*')
# log = lambda x: print(x)
map(log, [line for line in output if r.match(line)])
# def log_match(match):
#    if match: print(match)
#    return match  
if any(log_match(re.match(line)) for line in output):
    do_stuff()