如何在 Python 中替换(或删除)文件名的扩展名?

问题描述 投票:0回答:8

Python 中是否有一个内置函数可以替换(或删除,无论如何)文件名的扩展名(如果有的话)?

示例:

print replace_extension('/home/user/somefile.txt', '.jpg')

在我的例子中:

/home/user/somefile.txt
将变成
/home/user/somefile.jpg

我不知道这是否重要,但我正在编写的 SCons 模块需要它。 (所以也许我可以使用一些 SCons 特定功能?)

我想要一些干净的东西。对字符串中所有出现的 .txt

 进行简单的字符串替换显然是不干净的。 (如果我的文件名是
somefile.txt.txt.txt
,这将会失败)

python filenames scons strip
8个回答
319
投票
尝试

os.path.splitext 它应该做你想要的。

import os print os.path.splitext('/home/user/somefile.txt')[0]+'.jpg' # /home/user/somefile.jpg
os.path.splitext('/home/user/somefile.txt')  # returns ('/home/user/somefile', '.txt')
    

257
投票
扩展 AnaPana 的答案,如何使用

pathlib 删除扩展(Python >= 3.4):

>>> from pathlib import Path >>> filename = Path('/some/path/somefile.txt') >>> filename_wo_ext = filename.with_suffix('') >>> filename_replace_ext = filename.with_suffix('.jpg') >>> print(filename) /some/path/somefile.txt >>> print(filename_wo_ext) /some/path/somefile >>> print(filename_replace_ext) /some/path/somefile.jpg
    

62
投票
正如@jethro所说,

splitext

是最好的方法。但在这种情况下,您自己拆分它非常容易,因为扩展名 
必须是 文件名最后一个句点之后的部分:

filename = '/home/user/somefile.txt' print( filename.rsplit( ".", 1 )[ 0 ] ) # '/home/user/somefile'

rsplit

告诉Python从字符串右侧开始执行字符串拆分,
1
表示最多执行一次拆分(例如
'foo.bar.baz'
 -> 
[ 'foo.bar', 'baz' ]
)。由于 
rsplit
 始终返回一个非空数组,因此我们可以安全地将 
0
 索引到其中以获取减去扩展名的文件名。


24
投票
我更喜欢使用以下单行方法

str.rsplit():

my_filename.rsplit('.', 1)[0] + '.jpg'
示例:

>>> my_filename = '/home/user/somefile.txt' >>> my_filename.rsplit('.', 1) >>> ['/home/user/somefile', 'txt']
    

19
投票
处理多个扩展

如果您有多个扩展,使用

pathlib

str.replace
 会很不错:

移除/剥去延长线

>>> from pathlib import Path >>> p = Path("/path/to/myfile.tar.gz") >>> extensions = "".join(p.suffixes) # any python version >>> str(p).replace(extensions, "") '/path/to/myfile' # python>=3.9 >>> str(p).removesuffix(extensions) '/path/to/myfile'
更换扩展件

>>> p = Path("/path/to/myfile.tar.gz") >>> extensions = "".join(p.suffixes) >>> new_ext = ".jpg" >>> str(p).replace(extensions, new_ext) '/path/to/myfile.jpg'
如果您还想要一个 

pathlib

 对象输出,那么您显然可以将该行包裹在 
Path()

>>> Path(str(p).replace("".join(p.suffixes), "")) PosixPath('/path/to/myfile')
将其全部包装在一个函数中

from pathlib import Path from typing import Union PathLike = Union[str, Path] def replace_ext(path: PathLike, new_ext: str = "") -> Path: extensions = "".join(Path(path).suffixes) return Path(str(p).replace(extensions, new_ext)) p = Path("/path/to/myfile.tar.gz") new_ext = ".jpg" assert replace_ext(p, new_ext) == Path("/path/to/myfile.jpg") assert replace_ext(str(p), new_ext) == Path("/path/to/myfile.jpg") assert replace_ext(p) == Path("/path/to/myfile")
    

9
投票

TLDR: 在我看来,替换所有扩展的最佳方法如下。

import pathlib p = pathlib.Path('/path/to.my/file.foo.bar.baz.quz') print(p.with_name(p.name.split('.')[0]).with_suffix('.jpg'))

更长的答案: 执行此操作的最佳方法取决于您的 python 版本以及需要处理的扩展数量。也就是说,我很惊讶没有人提到 pathlib 的 with_name

。我还担心这里的一些答案无法处理父目录中的 
.
 。以下是完成扩展替换的几种方法。

使用路径对象

更换最多一个分机

import pathlib p = pathlib.Path('/path/to.my/file.foo') print(p.with_suffix('.jpg'))
更换最多两个扩展件

import pathlib p = pathlib.Path('/path/to.my/file.foo.bar') print(p.with_name(p.stem).with_suffix('.jpg'))
替换所有扩展

使用pathlibs

with_name

(我认为最好的解决方案):

import pathlib p = pathlib.Path('/path/to.my/file.foo.bar.baz.quz') print(p.with_name(p.name.split('.')[0]).with_suffix('.jpg'))
使用 

functools.reduce

 和 pathlib 的 
with_suffix
:

import pathlib import functools p = pathlib.Path('/path/to.my/file.foo.bar.baz.quz') print(functools.reduce(lambda v, _: v.with_suffix(''), p.suffixes, p).with_suffix('.jpg')) print(functools.reduce(lambda v, e: v.with_suffix(e), ['' for _ in p.suffixes] + ['.jpg'], p))

Python 3.9+使用pathlib和str.removesuffix:

import pathlib p = pathlib.Path('/path/to.my/file.foo.bar.baz.quz') print(pathlib.Path(str(p).removesuffix(''.join(p.suffixes))).with_suffix('.jpg'))
不使用路径对象(仅限字符串)

总的来说,我认为使用 pathlib 的解决方案更干净,但并不是每个人都能做到这一点。如果您仍在使用 python 2,我很抱歉。如果你没有python2的pathlib包,我真的很抱歉。

替换所有扩展

Python 2.7 兼容使用

os.path

:

import os ps = '/path/to.my/file.foo.bar.baz.quz' print(os.path.join(os.path.dirname(ps), os.path.basename(ps).split('.')[0] + '.jpg'))

Python 3.9+ 使用removesuffix

os.path
(如果你有python3.9,为什么不使用
pathlib
?):

import os ps = '/path/to.my/file.foo.bar.baz.quz' print(ps.removesuffix(os.path.splitext(ps)[-1].split('.', 1)[-1]) + 'jpg')
    

8
投票
另一种方法是使用

str.rpartition(sep)

 方法。 

例如:

filename = '/home/user/somefile.txt' (prefix, sep, suffix) = filename.rpartition('.') new_filename = prefix + '.jpg' print new_filename
    

7
投票
对于 Python >= 3.4:

from pathlib import Path filename = '/home/user/somefile.txt' p = Path(filename) new_filename = p.parent.joinpath(p.stem + '.jpg') # PosixPath('/home/user/somefile.jpg') new_filename_str = str(new_filename) # '/home/user/somefile.jpg'
    
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.