Python 如果列表中的任何字符串匹配正则表达式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37974047/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
If any strings in a list match regex
提问by ewok
I need to check if any of the strings in a list match a regex. If any do, I want to continue. The way I've always done it in the past is using list comprehension with something like:
我需要检查列表中的任何字符串是否与正则表达式匹配。如果有的话,我想继续。我过去一直这样做的方式是使用列表理解,例如:
r = re.compile('.*search.*')
if [line for line in output if r.match(line)]:
do_stuff()
Which I now realize is pretty inefficient. If the very first item in the list matches, we can skip all the rest of the comparisons and move on. I could improve this with:
我现在意识到这是非常低效的。如果列表中的第一项匹配,我们可以跳过所有其余的比较并继续。我可以通过以下方式改进:
r = re.compile('.*search.*')
for line in output:
if r.match(line):
do_stuff()
break
But I'm wondering if there's a more pythonic way to do this.
但我想知道是否有更 Pythonic 的方式来做到这一点。
回答by MrAlexBailey
You can use the builtin any()
:
您可以使用内置any()
:
if any(re.match(line) for line in output):
do_stuff()
Passing in the lazy generator to any()
will allow it to exit on the first match without having to check any farther into the iterable.
any()
传入惰性生成器 to将允许它在第一次匹配时退出,而无需进一步检查可迭代对象。
回答by Xavier Guihot
Starting Python 3.8
, and the introduction of assignment expressions (PEP 572)(:=
operator), we can also capture a witnessof an any
expression when a match is found and directly use it:
开始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'
For each item, this:
对于每个项目,这是:
- Applies the regex search (
pattern.match(x)
) - Assigns the result to a
match
variable (eitherNone
or are.Match
object) - Applies the truth value of
match
as part of the any expression (None
->False
,Match
->True
) - If
match
isNone
, then theany
search loop continues - If
match
has captured a group, then we exit theany
expression which is consideredTrue
and thematch
variable can be used within the condition's body
- 应用正则表达式搜索 (
pattern.match(x)
) - 将结果分配给
match
变量(None
或re.Match
对象) - 应用 的真值
match
作为 any 表达式的一部分 (None
->False
,Match
->True
) - 如果
match
是None
,则any
搜索循环继续 - 如果
match
已经捕获了一个组,那么我们退出any
被考虑的表达式True
并且match
变量可以在条件的主体中使用
回答by I. Jovanov
Given that I am not allowed to comment yet, I wanted to provide a small correction to MrAlexBailey's answer, and also answer nat5142's question. Correct form would be:
鉴于我还不能发表评论,我想对 MrAlexBailey 的回答做一个小的更正,并回答 nat5142 的问题。正确的形式是:
r = re.compile('.*search.*')
if any(r.match(line) for line in output):
do_stuff()
If you desire to find the matched string, you would do:
如果你想找到匹配的字符串,你可以这样做:
lines_to_log = [line for line in output if r.match(line)]
In addition, if you want to find all lines that match any compiled regular expression in a list of compiled regular expressions r=[r1,r2,...,rn], you can use:
此外,如果要在已编译正则表达式列表 r=[r1,r2,...,rn] 中查找与任何已编译正则表达式匹配的所有行,可以使用:
lines_to_log = [line for line in output if any(reg_ex.match(line) for reg_ex in r)]
回答by tinnick
In reply to a question asked by @nat5142, in the answer given by @MrAlexBailey: "Any way to access the matched string using this method? I'd like to print it for logging purposes", assuming "this" implies to:
回答@nat5142 提出的问题,在@MrAlexBailey 给出的答案中: “使用此方法访问匹配字符串的任何方式?我想打印它以进行日志记录”,假设“这个”意味着:
if any(re.match(line) for line in output):
do_stuff()
You can do a for loop over the generator
您可以对生成器执行 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
Another approach is mapping each match with the map function:
另一种方法是使用 map 函数映射每个匹配项:
# r = re.compile('.*search.*')
# log = lambda x: print(x)
map(log, [line for line in output if r.match(line)])
Although this does not involve the "any" function and might not even be close to what you desire...
虽然这不涉及“任何”功能,甚至可能不接近您想要的......
I thought this answer was not very relevant so here's my second attempt... I suppose you could do this:
我认为这个答案不是很相关,所以这是我的第二次尝试......我想你可以这样做:
# def log_match(match):
# if match: print(match)
# return match
if any(log_match(re.match(line)) for line in output):
do_stuff()