2017-05-30 137 views
2

我有这样的文件列表:如何过滤带有特定前缀和后缀(扩展名)的文件名?

file_list = ['file1.zip', 'file1.txt'] 
file_prefix = 'file1' 

我想使用filterre只得到file1.txt以上。我试试这个:

regex = re.compile(file_prefix + '.*(!zip).*') 
result = list(filter(regex.search, file_list)) 
# in the above, result should be populated with just ['file1.txt'] 

但是,正则表达式模式不起作用。有人可以帮我解决这个问题吗?非常感谢先进!

+1

用途: '(?!(\拉链*'re.compile file_prefix +)')' – anubhava

+0

有什么特别的理由使用正则表达式这样简单的模式匹配?这有点过头了...... – zwer

+0

@zwer你会推荐使用什么,而不是正则表达式? – user1330974

回答

2

可以使用负前瞻是这样的:

regex = re.compile(file_prefix + '(?!\.zip)') 

代码:

>>> file_list = ['file1.zip', 'file1.txt'] 
>>> file_prefix = 'file1' 
>>> regex = re.compile(file_prefix + '(?!\.zip)') 
>>> print list(filter(regex.search, file_list)) 
['file1.txt'] 

(?!\.zip)使得当.zip根本不存在下一个位置断言真正的负先行。

Read more about look-arounds

+2

谢谢!你能解释为什么我们需要添加''!'而不是'!'吗? – user1330974

+1

我已经添加了一些解释和一个很好的文档链接。 – anubhava

+1

这很有用。 –

2

无需正则表达式这个解决方案 - 你不需要把一门大炮来拇指斗争。使用Python的本地字符串搜索/检查:

file_list = ["file1.zip", "file1.txt"] 
file_prefix = "file1" 
file_exclude = "zip" 

result = [e for e in file_list if e.startswith(file_prefix) and not e.endswith(file_exclude)] 
# ['file1.txt'] 

也应该快得多。

如果不想仅搜索边缘,要过滤出没有zip后缀file_prefix不管它是字符串中(所以你要匹配some_file1.txt后的条目,甚至a_zip_file1.txt,但不是​​),你可以稍微修改:

file_list = ["file1.zip", "file1.txt", "some_file1.txt", "a_zip_file1.txt", "file1_zip.txt"] 
file_prefix = "file1" 
file_exclude = "zip" 

result = [e for e in file_list if e.find(file_exclude) < e.find(file_prefix)] 
# ['file1.txt', 'some_file1.txt', 'a_zip_file1.txt'] 
+0

感谢您分享替代方法。我不知道'find'(甚至是'starts/endswith')是否在Python后台场景中使用类似于regex的方法。但我必须同意,不使用正则表达式对于大多数读者来说更容易理解,并且可能像您说的那样更具性能。 – user1330974

+1

它不使用正则表达式,它使用纯C字符串操作(正则表达式引擎使用的东西,但它首先需要加载整个引擎,编译模式,创建分支......)底线,你应该使用这项工作的正确工具 - 在很多情况下,正则表达式会让你的生活更轻松(在某些情况下,它的运行速度将比单独通过Python字符串处理所做的更快),但这不是其中之一。 – zwer

+0

谢谢你的额外解释! – user1330974

相关问题