[英]How can I replace (or strip) an extension from a filename in Python?
Is there a built-in function in Python that would replace (or remove, whatever) the extension of a filename (if it has one)? Python 中是否有一个内置函数可以替换(或删除,无论如何)文件名的扩展名(如果有的话)?
Example:例子:
print replace_extension('/home/user/somefile.txt', '.jpg')
In my example: /home/user/somefile.txt
would become /home/user/somefile.jpg
在我的例子中:
/home/user/somefile.txt
将变成/home/user/somefile.jpg
I don't know if it matters, but I need this for a SCons module I'm writing.我不知道这是否重要,但是我正在编写的 SCons 模块需要这个。 (So perhaps there is some SCons specific function I can use ?)
(所以也许我可以使用一些 SCons 特定功能?)
I'd like something clean .我想要干净的东西。 Doing a simple string replacement of all occurrences of
.txt
within the string is obviously not clean.对字符串中所有出现的
.txt
进行简单的字符串替换显然是不干净的。 (This would fail if my filename is somefile.txt.txt.txt
) (如果我的文件名是
somefile.txt.txt.txt
这将失败)
Try os.path.splitext it should do what you want.试试os.path.splitext它应该做你想做的。
import os
print os.path.splitext('/home/user/somefile.txt')[0]+'.jpg'
Expanding on AnaPana's answer, how to remove an extension using pathlib (Python >= 3.4):扩展 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.ext
>>> print(filename_wo_ext)
/some/path/somefile
>>> print(filename_replace_ext)
/some/path/somefile.jpg
As @jethro said, splitext
is the neat way to do it.正如@jethro 所说,
splitext
是一种巧妙的方法。 But in this case, it's pretty easy to split it yourself, since the extension must be the part of the filename coming after the final period:但是在这种情况下,自己拆分它很容易,因为扩展名必须是最后一个句点之后的文件名的一部分:
filename = '/home/user/somefile.txt'
print( filename.rsplit( ".", 1 )[ 0 ] )
# '/home/user/somefile'
The rsplit
tells Python to perform the string splits starting from the right of the string, and the 1
says to perform at most one split (so that eg 'foo.bar.baz'
-> [ 'foo.bar', 'baz' ]
). rsplit
告诉 Python 从字符串的右侧开始执行字符串拆分,而1
表示最多执行一次拆分(例如'foo.bar.baz'
-> [ 'foo.bar', 'baz' ]
)。 Since rsplit
will always return a non-empty array, we may safely index 0
into it to get the filename minus the extension.由于
rsplit
将始终返回一个非空数组,我们可以安全地将0
索引到其中以获取文件名减去扩展名。
In the case where you have multiple extensions using pathlib
and str.replace
works a treat:在你有使用多个扩展名的情况下
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'
If you also want a pathlib
object output then you can obviously wrap the line in Path()
如果你还想要一个
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')
I prefer the following one-liner approach using str.rsplit() :我更喜欢使用str.rsplit()的以下单行方法:
my_filename.rsplit('.', 1)[0] + '.jpg'
Example:例子:
>>> my_filename = '/home/user/somefile.txt'
>>> my_filename.rsplit('.', 1)
>>> ['/home/user/somefile', 'txt']
Another way to do is to use the str.rpartition(sep)
method.另一种方法是使用
str.rpartition(sep)
方法。
For example:例如:
filename = '/home/user/somefile.txt'
(prefix, sep, suffix) = filename.rpartition('.')
new_filename = prefix + '.jpg'
print new_filename
For Python >= 3.4:对于 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'
Best way to replace all extensions, in my opinion:在我看来,替换所有扩展的最佳方法:
import pathlib
p = pathlib.Path('/path/to.my/file.foo.bar.baz.quz')
print(p.with_name(p.name.split('.')[0]))
Longer Answer: The best way to do this will depend on your version of python and how many extensions you need to handle.更长的答案:执行此操作的最佳方法将取决于您的 Python 版本以及您需要处理的扩展数量。 That said, I'm surprised nobody has mentioned pathlib's
with_name
.也就是说,我很惊讶没有人提到 pathlib 的
with_name
。 I'm also concerned that some answers here don't handle a .
我还担心这里的一些答案不处理
.
in the parent directories.在父目录中。 Here are several ways to accomplish extension replacement.
这里有几种方法可以完成扩展替换。
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'))
Using pathlibs with_name
(best solution, in my opinion):使用 pathlibs
with_name
(我认为最好的解决方案):
import pathlib
p = pathlib.Path('/path/to.my/file.foo.bar.baz.quz')
print(p.with_name(p.name.split('.')[0]))
Using functools.reduce
and pathlib's with_suffix
:使用
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+ Using pathlib and str.removesuffix: 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'))
In general, I think solutions using pathlib are cleaner, but not everybody can do that.总的来说,我认为使用 pathlib 的解决方案更简洁,但并不是每个人都能做到这一点。 If you're still using python 2, I'm sorry.
如果你还在使用 python 2,对不起。 If you don't have the pathlib package for python2, I'm really sorry.
如果你没有python2的pathlib包,我真的很抱歉。
Python 2.7 compatible using os.pathlib
:使用
os.pathlib
与 Python 2.7 兼容:
import os
ps = '/path/to.my/file.foo.bar.baz.quz'
print(ps.removesuffix(os.path.splitext(ps)[-1].split('.', 1)[-1]) + 'jpg')
Python 3.9+ Using removesuffix
and os.path
(if you have python3.9, why aren't you using pathlib
?): 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')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.