Python中fnmatch模块的使用详情


Posted in Python onNovember 30, 2018

fnamtch就是filenamematch, 在python中利用符合linuxshell风格的匹配模块来进行文件名的匹配筛选工作。

fnmatch()函数匹配能力介于简单的字符串方法和强大的正则表达式之间,如果在数据处理操作中只需要简单的通配符就能完成的时候,这通常是一个比较合理的方案。此模块的主要作用是文件名称的匹配,并且匹配的模式使用的Unix shell风格。源码很简单:

"""Filename matching with shell patterns.

fnmatch(FILENAME, PATTERN) matches according to the local convention.
fnmatchcase(FILENAME, PATTERN) always takes case in account.

The functions operate by translating the pattern into a regular
expression. They cache the compiled regular expressions for speed.

The function translate(PATTERN) returns a regular expression
corresponding to PATTERN. (It does not compile it.)
"""
import os
import posixpath
import re
import functools

__all__ = ["filter", "fnmatch", "fnmatchcase", "translate"]

def fnmatch(name, pat):
  """Test whether FILENAME matches PATTERN.

  Patterns are Unix shell style:

  *    matches everything
  ?    matches any single character
  [seq]  matches any character in seq
  [!seq] matches any char not in seq

  An initial period in FILENAME is not special.
  Both FILENAME and PATTERN are first case-normalized
  if the operating system requires it.
  If you don't want this, use fnmatchcase(FILENAME, PATTERN).
  """
  name = os.path.normcase(name)
  pat = os.path.normcase(pat)
  return fnmatchcase(name, pat)

@functools.lru_cache(maxsize=256, typed=True)
def _compile_pattern(pat):
  if isinstance(pat, bytes):
    pat_str = str(pat, 'ISO-8859-1')
    res_str = translate(pat_str)
    res = bytes(res_str, 'ISO-8859-1')
  else:
    res = translate(pat)
  return re.compile(res).match

def filter(names, pat):
  """Return the subset of the list NAMES that match PAT."""
  result = []
  pat = os.path.normcase(pat)
  match = _compile_pattern(pat)
  if os.path is posixpath:
    # normcase on posix is NOP. Optimize it away from the loop.
    for name in names:
      if match(name):
        result.append(name)
  else:
    for name in names:
      if match(os.path.normcase(name)):
        result.append(name)
  return result

def fnmatchcase(name, pat):
  """Test whether FILENAME matches PATTERN, including case.

  This is a version of fnmatch() which doesn't case-normalize
  its arguments.
  """
  match = _compile_pattern(pat)
  return match(name) is not None


def translate(pat):
  """Translate a shell PATTERN to a regular expression.

  There is no way to quote meta-characters.
  """

  i, n = 0, len(pat)
  res = ''
  while i < n:
    c = pat[i]
    i = i+1
    if c == '*':
      res = res + '.*'
    elif c == '?':
      res = res + '.'
    elif c == '[':
      j = i
      if j < n and pat[j] == '!':
        j = j+1
      if j < n and pat[j] == ']':
        j = j+1
      while j < n and pat[j] != ']':
        j = j+1
      if j >= n:
        res = res + '\\['
      else:
        stuff = pat[i:j].replace('\\','\\\\')
        i = j+1
        if stuff[0] == '!':
          stuff = '^' + stuff[1:]
        elif stuff[0] == '^':
          stuff = '\\' + stuff
        res = '%s[%s]' % (res, stuff)
    else:
      res = res + re.escape(c)
  return r'(?s:%s)\Z' % res

fnmatch的中的5个函数["filter", "fnmatch", "fnmatchcase", "translate"]

filter 返回列表形式的结果

def gen_find(filepat, top):
  """
  查找符合Shell正则匹配的目录树下的所有文件名
  :param filepat: shell正则
  :param top: 目录路径
  :return: 文件绝对路径生成器
  """
  for path, _, filenames in os.walk(top):
    for file in fnmatch.filter(filenames, filepat):
      yield os.path.join(path, file)

fnmatch

# 列出元组中所有的python文件
pyfiles = [py for py in ('restart.py', 'index.php', 'file.txt') if fnmatch(py, '*.py')]
# 字符串的 startswith() 和 endswith() 方法对于过滤一个目录的内容也是很有用的

fnmatchcase 区分大小写的文件匹配

# 这两个函数通常会被忽略的一个特性是在处理非文件名的字符串时候它们也是很有用的。 比如,假设你有一个街道地址的列表数据
address = [
  '5412 N CLARK ST',
  '1060 W ADDISON ST',
  '1039 W GRANVILLE AVE',
  '2122 N CLARK ST',
  '4802 N BROADWAY',
]
print([addr for addr in address if fnmatchcase(addr, '* ST')])

translate 这个似乎很少有人用到,前面说了fnmatch是Unix shell匹配风格,可以使用translate将其转换为正则表达式,举个栗子

shell_match = 'Celery_?*.py'
print(translate(shell_match))
# 输出结果:(?s:Celery_..*\.py)\Z

Celery_..*\.py就是正则表达式的写法。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 域名分析工具实现代码
Jul 15 Python
Python多线程结合队列下载百度音乐的方法
Jul 27 Python
Python多线程实现同步的四种方式
May 02 Python
python使用正则表达式的search()函数实现指定位置搜索功能
Nov 10 Python
Python 多维List创建的问题小结
Jan 18 Python
使用 Python 玩转 GitHub 的贡献板(推荐)
Apr 04 Python
Python生命游戏实现原理及过程解析(附源代码)
Aug 01 Python
PyTorch的Optimizer训练工具的实现
Aug 18 Python
Python 实现自动获取种子磁力链接方式
Jan 16 Python
关于tf.TFRecordReader()函数的用法解析
Feb 17 Python
ansible-playbook实现自动部署KVM及安装python3的详细教程
May 11 Python
在tensorflow下利用plt画论文中loss,acc等曲线图实例
Jun 15 Python
pycharm 解除默认unittest模式的方法
Nov 30 #Python
配置 Pycharm 默认 Test runner 的图文教程
Nov 30 #Python
基于python实现名片管理系统
Nov 30 #Python
django小技巧之html模板中调用对象属性或对象的方法
Nov 30 #Python
PyCharm鼠标右键不显示Run unittest的解决方法
Nov 30 #Python
python实现简单名片管理系统
Nov 30 #Python
python3学生名片管理v2.0版
Nov 29 #Python
You might like
Bo-Blog专用的给Windows服务器的IIS Rewrite程序
2007/08/26 PHP
php的正则处理函数总结分析
2008/06/20 PHP
php横向重复区域显示二法
2008/09/25 PHP
php cli 方式 在crotab中运行解决
2010/02/08 PHP
Yii框架组件和事件行为管理详解
2016/05/20 PHP
dojo 之基础篇(三)之向服务器发送数据
2007/03/24 Javascript
向fckeditor编辑器插入指定代码的方法
2007/05/25 Javascript
jQuery chili图片远处放大插件
2009/11/30 Javascript
用js实现输入提示(自动完成)的实例代码
2013/06/14 Javascript
jquery三个关闭弹出层的小示例
2013/11/05 Javascript
JS判断页面是否出现滚动条的方法
2015/07/17 Javascript
使用React实现轮播效果组件示例代码
2016/09/05 Javascript
jQuery在ie6下无法设置select选中的解决方法详解
2016/09/20 Javascript
DWR3 访问WEB元素的两种方法实例详解
2017/01/03 Javascript
Jquery树插件zTree实现菜单树
2017/01/24 Javascript
jQuery 1.9版本以上的浏览器判断方法代码分享
2017/08/28 jQuery
element-ui 中的table的列隐藏问题解决
2018/08/24 Javascript
在vue中使用SockJS实现webSocket通信的过程
2018/08/29 Javascript
vue随机验证码组件的封装实现
2020/02/19 Javascript
[01:04:35]2018DOTA2亚洲邀请赛 4.3 突围赛 Secret vs VG 第一场
2018/04/04 DOTA
Python设计模式之抽象工厂模式
2016/08/25 Python
Python正则表达式和re库知识点总结
2019/02/11 Python
python多线程http压力测试脚本
2019/06/25 Python
Python socket非阻塞模块应用示例
2019/09/12 Python
Django mysqlclient安装和使用详解
2020/09/17 Python
Python SMTP发送电子邮件的示例
2020/09/23 Python
Sephora丝芙兰马来西亚官方网站:国际化妆品购物
2018/03/15 全球购物
举例说明类变量和实例变量的区别
2016/06/30 面试题
珍珠鸟教学反思
2014/02/01 职场文书
群众路线教育党课主持词
2014/04/01 职场文书
财产公证书
2014/04/10 职场文书
竞选大队长演讲稿
2014/04/29 职场文书
2014年建筑工程工作总结
2014/12/03 职场文书
毕业典礼邀请函
2015/01/31 职场文书
使用canvas实现雪花飘动效果的示例代码
2021/03/30 HTML / CSS
详解Spring Bean的配置方式与实例化
2022/06/10 Java/Android