如果列表中的任何字符串与正则表达式匹配

时间:2016-06-22 16:48:57

标签: python regex

我需要检查列表中的任何字符串是否与正则表达式匹配。如果有的话,我想继续。我过去总是这样做的方式是使用列表理解,例如:

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

但我想知道是否有更多的pythonic方式来做到这一点。

4 个答案:

答案 0 :(得分:16)

您可以使用内置any()

if any(re.match(line) for line in output):
    do_stuff()

将延迟生成器传递给any()将允许它在第一个匹配时退出,而不必再检查迭代中的任何一个。

答案 1 :(得分:1)

鉴于尚未允许我发表评论,我想对AlexBailey先生的回答做一个小小的更正,并回答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)]

答案 2 :(得分:1)

Python 3.8开始并引入assignment expressions (PEP 572):=运算符),我们还可以在以下情况下捕获any表达式的 witness 找到一个匹配项并直接使用它:

# 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变量(Nonere.Match对象)
  • match的真值用作任何表达式的一部分(None-> FalseMatch-> True
  • 如果matchNone,则any搜索循环继续
  • 如果match捕获了一个组,则我们退出被认为是any的{​​{1}}表达式,并且True变量可以在条件体内使用

答案 3 :(得分:1)

在@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

另一种方法是使用map函数映射每个匹配项:

# 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()