在Python中从文件名中提取扩展名

Ale*_*lex 1167 python filenames file-extension

是否有从文件名中提取扩展名的功能?

nos*_*klo 1810

是.使用os.path.splitext(参见Python 2.X文档Python 3.X文档):

>>> import os
>>> filename, file_extension = os.path.splitext('/path/to/somefile.ext')
>>> filename
'/path/to/somefile'
>>> file_extension
'.ext'
Run Code Online (Sandbox Code Playgroud)

与大多数手动字符串拆分尝试不同,os.path.splitext将正确地/a/b.c/d视为没有扩展而不是扩展.c/d,并且它将被.bashrc视为没有扩展而不是扩展.bashrc:

>>> os.path.splitext('/a/b.c/d')
('/a/b.c/d', '')
>>> os.path.splitext('.bashrc')
('.bashrc', '')
Run Code Online (Sandbox Code Playgroud)

  • 标准的Python函数命名约定真的很烦人 - 几乎每次我重新查看它时,我都认为它是`splittext`.如果他们只是做任何事来表示这个名字的各个部分之间的中断,那么就会更容易认识到它是`splitExt`或`split_ext`.当然,我不能成为犯这个错误的唯一人吗? (139认同)
  • @ klingt.net嗯,在这种情况下,`.asd`真的是扩展!! 如果你考虑一下,`foo.tar.gz`是一个**gzip压缩文件**(`.gz`)恰好是一个**tar文件**(`.tar`).但它首先是**gzip文件**.我不希望它完全返回双扩展. (73认同)
  • 不会'endwith()`不是更便携和pythonic? (13认同)
  • 因为`os.path.basename("/ path/to/somefile.ext")`将返回`"somefile.ext",所以使用`basename`有点令人困惑. (12认同)
  • @Vingtoft您在评论中没有提到werkzeug的FileStorage,这个问题与该特定场景无关.如何传递文件名可能有问题.`os.path.splitext('somefile.ext')`=>`('somefile','.ext')`.在没有引用某些第三方库的情况下,随意提供一个实际的反例. (9认同)
  • 如果您的文件具有"双扩展名",例如`.mp3.asd`,则不能依赖它,因为它只返回"最后"扩展名! (7认同)
  • @Vingtoft结果相同的文件名或文件路径.请在只有文件名的情况下试一试,看看你在对这个备受推崇的答案提出反诉之前得到了什么. (7认同)
  • 另请参见下面有关`lower()`和double扩展的思想 (2认同)
  • @ ArtOfWarfare,IMO区分大小写的标识符将被记住,是有史以来最疯狂的设计决策之一。至少他们可以使用CamelCase命名函数,以使其更易于阅读。 (2认同)
  • @ArtOfWarfare鉴于`os.path`子模块的体积很小,您可以想象可以在保存在Python路径中的自己模块中手动重新映射名称。例如,“ myospath.py”包含诸如“ splitExt = os.path.splitext”之类的内容。 (2认同)

Bri*_*eal 372

import os.path
extension = os.path.splitext(filename)[1]
Run Code Online (Sandbox Code Playgroud)

  • 这实际上取决于你是否使用`from os import path`然后在你的本地范围内占用名称`path`,其他查看代码的人也可能不会立即知道路径是os模块的路径.就像你使用`import os.path`一样,它将它保存在`os`命名空间内,无论你在何处进行调用,人们都会立即知道``os`模块中的`path()`. (48认同)
  • 我知道它在语义上没有任何不同,但我个人觉得构造`_,extension = os.path.splitext(filename)`看起来更漂亮. (15认同)
  • 出于好奇,为什么`导入os.path`而不是`从os导入路径`? (12认同)
  • 哦,我只是想知道它背后是否有特定的原因(除了约定之外)。我仍在学习 Python 并想了解更多! (5认同)
  • 如果你想将扩展作为更复杂表达式的一部分,[1]可能更有用:`if check_for_gzip和os.path.splitext(filename)[1] =='.gz':` (3认同)

Jer*_*meJ 169

版本3.4中的新功能.

import pathlib

print(pathlib.Path('yourPathGoesHere').suffix)
Run Code Online (Sandbox Code Playgroud)

我很惊讶没有人提到过pathlib,pathlib太棒了!

如果您需要所有后缀(例如,如果您有.tar.gz),.suffixes将返回它们的列表!

  • 获取.tar.gz:`''.join(pathlib.Path('somedir/file.tar.gz').suffixes)的例子 (9认同)
  • @user3780389“foo.bar.tar.gz”不是仍然是有效的“.tar.gz”吗?如果是这样,您的代码片段应该使用 `.suffixes[-2:]` 以确保最多只获取 .tar.gz 。 (2认同)

won*_*bak 105

import os.path
extension = os.path.splitext(filename)[1][1:]
Run Code Online (Sandbox Code Playgroud)

仅获取扩展名的文本,不带点.

  • 对于以“.”结尾的文件名和不带扩展名的文件名,这将返回空。 (2认同)

Mur*_*rlu 68

一个选项可能是从点分割:

>>> filename = "example.jpeg"
>>> filename.split(".")[-1]
'jpeg'
Run Code Online (Sandbox Code Playgroud)

文件没有扩展名时没有错误:

>>> "filename".split(".")[-1]
'filename'
Run Code Online (Sandbox Code Playgroud)

但你必须小心:

>>> "png".split(".")[-1]
'png'    # But file doesn't have an extension
Run Code Online (Sandbox Code Playgroud)

  • 并不是.名为"x.tar.gz"的文件的扩展名为"gz"而不是"tar.gz".os.path.splitext也将".os"作为扩展名. (18认同)
  • [-1]获取按点分割的项目的最后一项.示例:`"my.file.name.js".split('.')=> ['my','file','name','js]` (7认同)
  • 如果您要上传x.tar.gz,这会让您感到不安 (4认同)
  • 我们可以使用 [1] 而不是 [-1]。我无法理解 [-1] 与 split (2认同)
  • @BenjaminR 好吧,您正在对结果列表进行优化。`['file', 'tar', 'gz']` 和 `'file.tar.gz'.split('.')` **vs** `['file.tar', 'gz']`用`'file.tar.gz'.rsplit('.', 1)`。是的,可能是。 (2认同)

ble*_*ted 35

值得在那里添加一个较低的,所以你不会发现自己想知道为什么JPG没有出现在你的列表中.

os.path.splitext(filename)[1][1:].strip().lower()
Run Code Online (Sandbox Code Playgroud)


小智 16

上面的任何解决方案都有效,但是在Linux上我发现扩展字符串末尾有一个换行符会阻止匹配成功.将strip()方法添加到最后.例如:

import os.path
extension = os.path.splitext(filename)[1][1:].strip() 
Run Code Online (Sandbox Code Playgroud)


Xav*_*CLL 14

随着splitext有与双扩展名的文件的问题(例如file.tar.gz,file.tar.bz2等..)

>>> fileName, fileExtension = os.path.splitext('/path/to/somefile.tar.gz')
>>> fileExtension 
'.gz'
Run Code Online (Sandbox Code Playgroud)

但应该是: .tar.gz

可能的解决方案在这里

  • 不,它应该是.gz (33认同)
  • 这就是为什么我们有扩展名“tgz”,意思是:tar+gzip!:D (2认同)

小智 11

虽然这是一个古老的话题,但我想知道为什么在这种情况下没有提到一个叫做rpartition的非常简单的pyi api:

要获得给定文件绝对路径的扩展,您只需键入:

filepath.rpartition('.')[-1]
Run Code Online (Sandbox Code Playgroud)

例:

path = '/home/jersey/remote/data/test.csv'
print path.rpartition('.')[-1]
Run Code Online (Sandbox Code Playgroud)

会给你:'csv'

  • 对于那些不熟悉 API 的人,[rpartition](https://docs.python.org/3/library/stdtypes.html#str.rpartition) 返回一个元组:`("string 在最右边出现的分隔符”、“分隔符本身”、“字符串的其余部分”)`。如果没有找到分隔符,返回的元组将是:`("", "", "the original string")`。 (2认同)

Pas*_*ten 10

感到惊讶的是还没有提到:

import os
fn = '/some/path/a.tar.gz'

basename = os.path.basename(fn)  # os independent
Out[] a.tar.gz

base = basename.split('.')[0]
Out[] a

ext = '.'.join(basename.split('.')[1:])   # <-- main part

# if you want a leading '.', and if no result `None`:
ext = '.' + ext if ext else None
Out[] .tar.gz
Run Code Online (Sandbox Code Playgroud)

优点:

  • 对于我能想到的任何事情都可以正常工作
  • 没有模块
  • 没有正则表达式
  • 跨平台
  • 易于扩展(例如,没有前导点用于扩展,只有扩展的最后部分)

作为功​​能:

def get_extension(filename):
    basename = os.path.basename(filename)  # os independent
    ext = '.'.join(basename.split('.')[1:])
    return '.' + ext if ext else None
Run Code Online (Sandbox Code Playgroud)

  • 如果文件名在名称中包含许多点,则此答案绝对会忽略变体。示例 get_extension('cmocka-1.1.0.tar.xz') =&gt; '.1.0.tar.xz' - 错误。 (5认同)
  • 当文件没有任何扩展名时,这会导致异常。 (2认同)
  • 只需更改为“[-1]”即可。 (2认同)

dat*_*ght 10

在Python中从文件名中提取扩展名

\n

Python os 模块 splitext()

\n

splitext()函数将文件路径拆分为具有两个值 \xe2\x80\x93 根和扩展名的元组。

\n
import os\n# unpacking the tuple\nfile_name, file_extension = os.path.splitext("/Users/Username/abc.txt")\nprint(file_name)\nprint(file_extension)\n
Run Code Online (Sandbox Code Playgroud)\n

使用 Pathlib 模块获取文件扩展名

\n

Pathlib模块获取文件扩展名

\n
import pathlib\npathlib.Path("/Users/pankaj/abc.txt").suffix\n#output:'.txt'\n
Run Code Online (Sandbox Code Playgroud)\n


小智 9

filename='ext.tar.gz'
extension = filename[filename.rfind('.'):]
Run Code Online (Sandbox Code Playgroud)

  • 如果文件名根本没有“.”,这将导致返回“文件名”的最后一个字符。这是因为如果找不到字符串,`rfind` 会返回 `-1`。 (2认同)

r3t*_*t40 9

你可以在pathlib模块中找到一些很棒的东西.

import pathlib
x = pathlib.PurePosixPath("C:\\Path\\To\\File\\myfile.txt").suffix
print(x)

# Output 
'.txt'
Run Code Online (Sandbox Code Playgroud)

  • 使用 PosixPath 作为 Windows 路径是错误的。 (2认同)

Ale*_*lex 8

只是join全部pathlib suffixes

>>> x = 'file/path/archive.tar.gz'
>>> y = 'file/path/text.txt'
>>> ''.join(pathlib.Path(x).suffixes)
'.tar.gz'
>>> ''.join(pathlib.Path(y).suffixes)
'.txt'
Run Code Online (Sandbox Code Playgroud)


soh*_*shi 7

您可以在split上使用filename

f_extns = filename.split(".")
print ("The extension of the file is : " + repr(f_extns[-1]))
Run Code Online (Sandbox Code Playgroud)

这不需要额外的库


Arn*_*ira 5

另一个正确拆分的解决方案:

# to get extension only

s = 'test.ext'

if '.' in s: ext = s.rsplit('.', 1)[1]

# or, to get file name and extension

def split_filepath(s):
    """
    get filename and extension from filepath 
    filepath -> (filename, extension)
    """
    if not '.' in s: return (s, '')
    r = s.rsplit('.', 1)
    return (r[0], r[1])
Run Code Online (Sandbox Code Playgroud)


小智 5

即使已经回答了这个问题,我也会在 Regex 中添加解决方案。

>>> import re
>>> file_suffix = ".*(\..*)"
>>> result = re.search(file_suffix, "somefile.ext")
>>> result.group(1)
'.ext'
Run Code Online (Sandbox Code Playgroud)

  • 或者如[这篇文章](/sf/ask/460752001/)中的`\.[0-9a-z]+$`。 (2认同)

小智 5

这是一种直接的字符串表示技术:我看到了很多解决方案,但我认为大多数都在考虑拆分。但是,每次出现“。”时都会进行拆分。。您宁愿寻找的是分区。

string = "folder/to_path/filename.ext"
extension = string.rpartition(".")[-1]
Run Code Online (Sandbox Code Playgroud)

  • [@weiyixie](/sf/answers/2973428531/)已建议使用rpartition。 (2认同)

小智 5

您可以使用以下代码来拆分文件名和扩展名。

    import os.path
    filenamewithext = os.path.basename(filepath)
    filename, ext = os.path.splitext(filenamewithext)
    #print file name
    print(filename)
    #print file extension
    print(ext)
Run Code Online (Sandbox Code Playgroud)