在Python中从文件名中提取文件扩展名的方法是什么?

时间:2013-06-07 04:24:29

标签: python string

文件名是动态的,我需要提取文件扩展名。文件名如下所示: parallels-workstation-parallels-en_US-6.0.13976.769982.run.sh

20090209.02s1.1_sequence.txt
SRR002321.fastq.bz2
hello.tar.gz
ok.txt

对于我要提取txt的第一个,我要提取fastq.bz2的第二个,我要提取tar.gz的第三个。

我使用os模块获取文件扩展名为:

import os.path
extension = os.path.splitext('hello.tar.gz')[1][1:]

这只给我gz,如果文件名是ok.txt则没问题,但对于这个,我希望扩展名为tar.gz

6 个答案:

答案 0 :(得分:4)

import os

def splitext(path):
    for ext in ['.tar.gz', '.tar.bz2']:
        if path.endswith(ext):
            return path[:-len(ext)], path[-len(ext):]
    return os.path.splitext(path)

assert splitext('20090209.02s1.1_sequence.txt')[1] == '.txt'
assert splitext('SRR002321.fastq.bz2')[1] == '.bz2'
assert splitext('hello.tar.gz')[1] == '.tar.gz'
assert splitext('ok.txt')[1] == '.txt'

删除点:

import os

def splitext(path):
    for ext in ['.tar.gz', '.tar.bz2']:
        if path.endswith(ext):
            path, ext = path[:-len(ext)], path[-len(ext):]
            break
    else:
        path, ext = os.path.splitext(path)
    return path, ext[1:]

assert splitext('20090209.02s1.1_sequence.txt')[1] == 'txt'
assert splitext('SRR002321.fastq.bz2')[1] == 'bz2'
assert splitext('hello.tar.gz')[1] == 'tar.gz'
assert splitext('ok.txt')[1] == 'txt'

答案 1 :(得分:2)

您的规则是任意的,当扩展程序中有.时,计算机应该如何猜测?

充其量你必须有一套特殊的扩展,例如{'.bz2', '.gz'}并自己添加一些额外的逻辑

>>> paths = """20090209.02s1.1_sequence.txt
... SRR002321.fastq.bz2
... hello.tar.gz
... ok.txt""".splitlines()
>>> import os
>>> def my_split_ext(path):
...     name, ext = os.path.splitext(path)
...     if ext in {'.bz2', '.gz'}:
...         name, ext2 = os.path.splitext(name)
...         ext = ext2 + ext
...     return name, ext
... 
>>> map(my_split_ext, paths)
[('20090209.02s1.1_sequence', '.txt'), ('SRR002321', '.fastq.bz2'), ('hello', '.tar.gz'), ('ok', '.txt')]

答案 2 :(得分:1)

> import re
> re.search(r'\.(.*)', 'hello.tar.gz').groups()[0]
'tar.gz'

显然上面假设有一个.,但它看起来不像os.path会在这里做你想要的。

答案 3 :(得分:0)

好吧,你可以继续在root上迭代,直到ext为空。换句话说:

filename = "hello.tar.gz"
extensions = []
root, ext = os.path.splitext(filename)
while ext:
    extensions.append(ext)
    root, ext = os.path.splitext(root)

# do something if extensions length is greater than 1

答案 4 :(得分:0)

我知道这是一个非常古老的话题,但对于遇到这个话题的其他人,我想分享我的解决方案(我同意这取决于你的程序逻辑)。

我只需要没有扩展名的基本名称,你可以根据需要随时使用splitext,这使得spitext返回(base,ext),其中base始终是basename,ext只包含一个扩展名,如果找到的话。 因此,对于具有单周期或双周期的文件(例如.tar.gz和.txt),以下内容始终返回基本名称:

base = os.path.splitext(os.path.splitext(filename)[0])[0]

答案 5 :(得分:0)

如果你希望你的文件名包含点,

splittext通常不是一个好的选择,而是我更喜欢:

>> import re
>> re.compile("(?P<name>.+?)(\.(?P<extension>.{1,4}))?$").search("blabla.blublu.tmp").groupdict()
{'extension': 'tmp', 'name': 'blabla.blublu'}
>> re.compile("(?P<name>.+?)(\.(?P<extension>.{1,4}))?$").search("blabla.blublu.tmpmoreblabla").groupdict()
{'extension': None, 'name': 'blabla.blublu.tmpmoreblabla'}
>> re.compile("(?P<name>.+?)(\.(?P<extension>.{1,4}))?$").search("blabla.blublu.tmpmoreblabla.ext").groupdict()
{'extension': 'ext', 'name': 'blabla.blublu.tmpmoreblabla'}

只检查第二种情况"blabla.blublu.tmpmoreblabla",如果这是一个没有扩展名的文件名,splittext仍然会返回tmpmoreblabla作为扩展名,您对此代码的唯一假设是:

  1. 您总是将非空字符串作为输入
  2. 您的文件名和扩展程序可能包含任何可能的字符
  3. 您的文件扩展名长度介于1或4个字符之间(如果有) 更多的角色,它不会被视为一个扩展,但名称的一部分)
  4. 您的字符串以扩展名文件
  5. 结尾

    当然你可以使用未命名的组只删除?P<>,但在这种情况下我更喜欢命名组