V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
syaokun219
V2EX  ›  问与答

菜鸟问个问题哈,如何用 python 找到没有扩展名的文件呢,一直不知道是怎么匹配的呢,其实主要还是正则表达式学的不好

  •  
  •   syaokun219 · 2014-08-06 22:30:47 +08:00 · 6202 次点击
    这是一个创建于 3542 天前的主题,其中的信息可能已经有所发展或是发生改变。
    25 条回复    2014-08-08 10:32:02 +08:00
    oseau
        1
    oseau  
       2014-08-07 04:22:22 +08:00   ❤️ 1
    试试 ^[^.]+$
    Sylv
        2
    Sylv  
       2014-08-07 05:25:13 +08:00 via iPhone
    '.' not in filename
    yangqi
        3
    yangqi  
       2014-08-07 07:20:21 +08:00
    @oseau
    @Sylv 你们难道不考虑文件名中有.的情况?
    oseau
        4
    oseau  
       2014-08-07 07:55:11 +08:00
    @yangqi
    "A filename extension is a suffix (separated from the base filename by a dot or space) to the name of a computer file applied to indicate the encoding (file format) of its contents or usage."
    参考 http://en.wikipedia.org/wiki/Filename_extension
    通常使用句号'.'作为分隔符
    lrz0lrz
        5
    lrz0lrz  
       2014-08-07 08:19:46 +08:00
    文件名中有“.”就算是有了扩展名,不管“.”后面是什么。
    yangqi
        6
    yangqi  
       2014-08-07 08:30:23 +08:00   ❤️ 1
    @oseau test-v1.0-stable.tar.gz
    loading
        7
    loading  
       2014-08-07 08:48:05 +08:00 via Android
    @yangqi
    .gz 是 gnuzip 的压缩包是 zip 的gnu版
    .tar 是 tar 命令打出来的包,没压缩

    所以 tar.gz 是告诉软件和你,这个包是包成了 tar 然后用 gz 压缩过!
    类似有 tar.bz2

    当然,文件类型都在文件头有信息
    yangqi
        8
    yangqi  
       2014-08-07 09:34:08 +08:00
    @loading 你根本没明白我的意思
    oseau
        9
    oseau  
       2014-08-07 09:39:13 +08:00   ❤️ 1
    @yangqi 我的理解是你想说形如‘test-v1.0-stable’这样的文件应该视为没有扩展名的文件。 如果按照扩展名为3个字符以内的约定。可以使用 .+?\.[^\.]{4,}$
    这样形如
    test-v1.0-stable
    .test-v1.0-stable
    都可以match。
    而 test-stable-v1.0 这样的不能match
    按楼主要求使用正则的话目前就想到这么多。 选择性参考。
    decken
        10
    decken  
       2014-08-07 09:39:39 +08:00
    @yangqi 你的意思是beta v0.1这样的文件也算没有扩展名吗?
    decken
        11
    decken  
       2014-08-07 09:41:24 +08:00
    @decken 9楼正解
    loading
        12
    loading  
       2014-08-07 10:15:54 +08:00 via Android
    @yangqi
    哦,我知道了。那样的话,需要一个有效拓展名列表!
    binux
        13
    binux  
       2014-08-07 10:22:44 +08:00
    @yangqi 你就不允许人家拓展名叫 0-stable 吗!
    mhycy
        14
    mhycy  
       2014-08-07 11:06:29 +08:00
    直接做个函数做判断好了。。。简单明了
    halfelf
        15
    halfelf  
       2014-08-07 11:30:32 +08:00
    实际上os.path.splitext都只是按.来split
    halfelf
        16
    halfelf  
       2014-08-07 11:38:22 +08:00
    提供一个库方案:mimetypes.guess_type,返回(None, None)就没扩展
    hahastudio
        17
    hahastudio  
       2014-08-07 11:40:20 +08:00
    @oseau 1.docx 也要算是没有扩展名的文件么= =
    hahastudio
        18
    hahastudio  
       2014-08-07 11:54:06 +08:00
    从 SO 上看到的: http://stackoverflow.com/questions/9001557/match-filename-and-file-extension-from-single-regex
    ^([^\\]*)\.(\w+)$
    可以匹配 index.html, 1.docx, pack.7z, ring.mp3, .bash_profile 等等,不会匹配test-v1.0-stable
    但是看 wikipedia 上面的扩展名列表,发现不少猎奇的= =
    http://en.wikipedia.org/wiki/Alphabetical_list_of_filename_extensions_(A%E2%80%93E)
    像 temp.$$$ 就没法匹配
    imn1
        19
    imn1  
       2014-08-07 13:34:09 +08:00
    @lrz0lrz 只有一个点并且在最后呢?
    syaokun219
        20
    syaokun219  
    OP
       2014-08-08 08:02:55 +08:00
    @hahastudio 大神看我代码,为啥匹配不到呢
    # -*- coding: utf-8 -*-
    #########################################################################
    # Author: Yao Kun
    # Created Time: 五 8/ 8 07:42:26 2014
    # File Name: testmac.py
    # Description:
    #########################################################################
    import os
    # 用于获得操作系统信息
    import platform
    import fnmatch

    print "尝试删除扩展名为空,或者是不需要同步的文件"

    sys = platform.system()
    if sys == "Darwin":
    sys = "Mac OS X"
    print "Your system is", sys, ", this is a delete-file script..."
    else:
    print "您的操作系统是", sys, ",这是删除文件脚本"

    def iterfindfiles(path, fnexp):
    for root, dirs, files in os.walk(path):
    # 遍历某个目录
    for filename in fnmatch.filter(files, fnexp):
    yield os.path.join(root, filename)

    if sys == "Mac OS X":
    search_path = r"/Users/mac-prisonbreak/百度云同步盘/"
    else:
    search_path = r"D:/百度云/Project"

    print "Your current search dir is", search_path

    flag = False
    command = "check"

    logfile = open("delete_log.txt", "w+")
    for filename in iterfindfiles(search_path, "^([^\\]*)\.(\w+)$"):
    print filename
    logfile.write("\n"+filename)
    # 删除是危险操作,需要确认
    if command == "all" or command == "yes":
    os.remove(filename)

    if command == "yes":
    command = "check"
    elif command == "none":
    pass
    print "Do nothing"
    else:
    command = raw_input()
    #关闭文件
    logfile.close()
    syaokun219
        21
    syaokun219  
    OP
       2014-08-08 08:05:22 +08:00
    @oseau 匹配不到呀,我上面贴了一下代码
    syaokun219
        22
    syaokun219  
    OP
       2014-08-08 08:12:49 +08:00
    @hahastudio 我知道了,好像是这个fnmatch的问题哈
    hahastudio
        23
    hahastudio  
       2014-08-08 09:34:05 +08:00
    @syaokun219 我用 re 简单试的= =
    oseau
        24
    oseau  
       2014-08-08 10:22:10 +08:00
    @decken
    之前的有点问题 应该改成 .+?\.?[^\.]{4,}$
    oseau
        25
    oseau  
       2014-08-08 10:32:02 +08:00   ❤️ 1
    @syaokun219
    fnmatch的文档里第一句写着呢。
    This module provides support for Unix shell-style wildcards, which are NOT the same as regular expressions。
    它用的pattern不是正则表达式。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4058 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 00:58 · PVG 08:58 · LAX 17:58 · JFK 20:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.