使用 re.match 过滤字符串列表时失败 [重复]
Posted
技术标签:
【中文标题】使用 re.match 过滤字符串列表时失败 [重复]【英文标题】:Failure when filtering string list with re.match [duplicate] 【发布时间】:2016-03-11 03:12:33 【问题描述】:我想使用正则表达式过滤 python 中的字符串列表。在以下情况下,仅保留扩展名为“.npy”的文件。
不起作用的代码:
import re
files = [ '/a/b/c/la_seg_x005_y003.png',
'/a/b/c/la_seg_x005_y003.npy',
'/a/b/c/la_seg_x004_y003.png',
'/a/b/c/la_seg_x004_y003.npy',
'/a/b/c/la_seg_x003_y003.png',
'/a/b/c/la_seg_x003_y003.npy', ]
regex = re.compile(r'_x\d+_y\d+\.npy')
selected_files = filter(regex.match, files)
print(selected_files)
同样的正则表达式在 Ruby 中也适用于我:
selected = files.select |f| f =~ /_x\d+_y\d+\.npy/
Python 代码有什么问题?
【问题讨论】:
你想用.npy
扩展过滤files
中的元素吗?
【参考方案1】:
只需使用search
- 因为匹配从字符串的开头到结尾(即整个)开始匹配,并在字符串中的任何位置搜索匹配项。
import re
files = [ '/a/b/c/la_seg_x005_y003.png',
'/a/b/c/la_seg_x005_y003.npy',
'/a/b/c/la_seg_x004_y003.png',
'/a/b/c/la_seg_x004_y003.npy',
'/a/b/c/la_seg_x003_y003.png',
'/a/b/c/la_seg_x003_y003.npy', ]
regex = re.compile(r'_x\d+_y\d+\.npy')
selected_files = filter(regex.search, files)
print(selected_files)
输出-
['/a/b/c/la_seg_x005_y003.npy', '/a/b/c/la_seg_x004_y003.npy', '/a/b/c/la_seg_x003_y003.npy']
【讨论】:
【参考方案2】:如果您match,则该模式必须覆盖整个输入。 要么扩展你的正则表达式:
regex = re.compile(r'.*_x\d+_y\d+\.npy')
哪个匹配:
['/a/b/c/la_seg_x005_y003.npy',
'/a/b/c/la_seg_x004_y003.npy',
'/a/b/c/la_seg_x003_y003.npy']
或者使用re.search,其中
扫描字符串寻找正则表达式模式产生匹配的第一个位置 [...]
【讨论】:
【参考方案3】:re.match()
在字符串的开头查找匹配项。你可以改用re.search()
。
【讨论】:
【参考方案4】:selected_files = filter(regex.match, files)
re.match('regex')
等于 re.search('^regex')
或 text.startswith('regex')
但正则表达式版本。 它只检查字符串是否以正则表达式开头。
所以,请改用re.search()
:
import re
files = [ '/a/b/c/la_seg_x005_y003.png',
'/a/b/c/la_seg_x005_y003.npy',
'/a/b/c/la_seg_x004_y003.png',
'/a/b/c/la_seg_x004_y003.npy',
'/a/b/c/la_seg_x003_y003.png',
'/a/b/c/la_seg_x003_y003.npy', ]
regex = re.compile(r'_x\d+_y\d+\.npy')
selected_files = list(filter(regex.search, files))
# The list call is only required in Python 3, since filter was changed to return a generator
print(selected_files)
输出:
['/a/b/c/la_seg_x005_y003.npy',
'/a/b/c/la_seg_x004_y003.npy',
'/a/b/c/la_seg_x003_y003.npy']
如果您只想获取所有.npy
文件,str.endswith()
将是更好的选择:
files = [ '/a/b/c/la_seg_x005_y003.png',
'/a/b/c/la_seg_x005_y003.npy',
'/a/b/c/la_seg_x004_y003.png',
'/a/b/c/la_seg_x004_y003.npy',
'/a/b/c/la_seg_x003_y003.png',
'/a/b/c/la_seg_x003_y003.npy', ]
selected_files = list(filter(lambda x: x.endswith('.npy'), files))
print(selected_files)
【讨论】:
我想知道为什么filter()
接受re.search()
方法,因为后者返回MatchObject
的实例而不是布尔值。在 16.8.3 中解释了here:如果项目匹配,search()
-方法返回一个 MatchObject,filter()
将其解释为 True。否则search()
返回 None,它被解释为 False。
在 Python 3.x 中,filter()
returns a generator,所以如果你想要的话,你需要将它包装在 list()
中。以上是关于使用 re.match 过滤字符串列表时失败 [重复]的主要内容,如果未能解决你的问题,请参考以下文章