4

文件名是动态的,我需要提取文件扩展名。文件名如下所示: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.

4

6 回答 6

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'
于 2013-06-07T04:37:23.773 回答
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')]
于 2013-06-07T04:32:24.273 回答
1
> import re
> re.search(r'\.(.*)', 'hello.tar.gz').groups()[0]
'tar.gz'

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

于 2013-06-07T04:37:54.750 回答
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
于 2013-06-07T04:37:55.107 回答
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. 您的字符串以扩展文件结尾

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

于 2016-05-18T09:07:17.687 回答
0

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

我只需要没有扩展名的基本名称,您可以根据需要随时拆分文本,这使得 spitext 返回 (base,ext) 其中 base 始终是基本名称,而 ext 仅在找到扩展名时才包含扩展名。因此,对于具有单句点或双句点的文件(例如 .tar.gz 和 .txt),以下始终返回基本名称:

base = os.path.splitext(os.path.splitext(filename)[0])[0]
于 2015-12-28T02:50:57.310 回答