[英]If any strings in a list match 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 的方式來做到這一點。
您可以使用內置any()
:
r = re.compile('.*search.*')
if any(r.match(line) for line in output):
do_stuff()
將惰性生成器傳遞給any()
將允許它在第一次匹配時退出,而無需進一步檢查可迭代對象。
從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'
對於每個項目,這是:
pattern.match(x)
)match
變量( None
或re.Match
對象)match
的真值作為 any 表達式的一部分( None
-> False
, Match
-> True
)match
為None
,則any
搜索循環繼續match
捕獲了一個組,那么我們退出被認為是True
的any
表達式,並且可以在條件的主體中使用match
變量鑒於我還不能發表評論,我想對 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)]
回答@nat5142 提出的問題,在@MrAlexBailey 給出的答案中: “使用此方法訪問匹配字符串的任何方式?我想打印它以進行日志記錄” ,假設“這個”意味着:
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()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.