【问题标题】:Getting file names without file extensions with glob使用 glob 获取没有文件扩展名的文件名
【发布时间】:2018-06-18 16:31:18
【问题描述】:

我只搜索 .txt 文件

from glob import glob
result = glob('*.txt')

>> result
['text1.txt','text2.txt','text3.txt']

但我想要result 没有文件扩展名

>> result
['text1','text2','text3']

是否有可以与glob 一起使用的正则表达式模式来从输出中排除文件扩展名,还是我必须对result 使用列表理解?

【问题讨论】:

  • 你的标题有点误导,Getting file names without file extension with glob会更好吗?
  • @Simon 同意。标题听起来像是在寻找 libmagic 或其他一些启发式方法来检测文本文件。你的重写对我来说听起来不错。
  • @abarnert 我应该自己编辑吗?未经 OP 同意?
  • 附带说明:glob 不采用正则表达式模式,它采用全局模式,这是另一回事。在幕后,它确实构建了正则表达式模式以应用于文件列表,但您看不到这些。 (如果您想查看它们,请参阅fnmatch 模块。)
  • @Simon 我认为这很好。如果他们不同意,OP 总是可以回复,如果不同意,你已经为他们改进了他们的问题。

标签: python glob


【解决方案1】:

glob() 无法做到这一点,您需要获取给定的列表,然后创建一个新列表来存储没有扩展名的值:

import os
from glob import glob

[os.path.splitext(val)[0] for val in glob('*.txt')]

os.path.splitext(val) 将文件名拆分为文件名和扩展名。 [0] 只返回文件名。

【讨论】:

    【解决方案2】:

    由于您尝试拆分文件扩展名,而不是拆分任意字符串,因此使用os.path.splitext(或pathlib 模块)更有意义。虽然它确实在当前唯一重要的平台(Windows 和 *nix)上没有实际差异,但它仍然在概念上更清楚你在做什么。 (如果您稍后开始使用类似路径的对象而不是字符串,它将继续保持不变,以启动。)

    所以:

    paths = [os.path.splitext(path)[0] for path in paths]
    

    同时,如果这真的因为某种原因冒犯了您,glob 在幕后所做的只是调用fnmatch 将您的 glob 表达式转换为正则表达式,然后将其应用于所有文件名。因此,您可以通过自己替换正则表达式并使用捕获组来替换它:

    rtxt = re.compile(r'(.*?)\.txt')
    files = (rtxt.match(file) for file in os.listdir(dirpath))
    files = [match.group(1) for match in files if match]
    

    这样,您不会在 glob 中已经存在的列表之上进行列表计算;你正在做一个而不是已经在glob中的那个。我不确定这是否是一个有用的胜利,但既然你似乎有兴趣消除一个列表竞争......

    【讨论】:

    • @abanert:感谢您的详细解释。
    【解决方案3】:

    使用索引切片:

    result = [i[:-4] for i in result]
    

    【讨论】:

    • 这行得通,但不如使用splitext 甚至rsplit 清晰或健壮。例如,如果您稍后将代码更改为同时接受.txt.text,则其他解决方案会继续工作,但这个不会。
    【解决方案4】:

    使用rsplit的另一种方式:

    >>> result = ['text1.txt','text2.txt.txt','text3.txt']
    >>> [x.rsplit('.txt', 1)[0] for x in result]
    ['text1', 'text2.txt', 'text3']
    

    你可以做一个列表理解:

    result = [x.rsplit(".txt", 1)[0] for x in glob('*.txt')]
    

    【讨论】:

    • 为什么不只是rsplit('.')
    • @abarnert 确定这也有效。但我认为它更好地使用.txt,因为 OP 是特定于 .txt 文件的。
    【解决方案5】:

    这个 glob 只选择没有扩展名的文件:**/*/!(*.*)

    【讨论】:

      【解决方案6】:

      使用str.split

      >>> result = [r.split('.')[0] for r in glob('*.txt')]
      >>> result
      ['text1', 'text2', 'text3']
      

      【讨论】:

      • 这会为text.file.10.txt 做错误的事情,返回text 而不是text.file.10(这在某些过时的平台上是正确的,但在Windows 或Unix 上不是)。
      猜你喜欢
      • 2021-07-18
      • 1970-01-01
      • 2015-02-14
      • 1970-01-01
      • 2017-10-28
      • 2011-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多