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 相关文章推荐
pyqt4教程之widget使用示例分享
Mar 07 Python
Python自动化运维_文件内容差异对比分析
Dec 13 Python
Python3中bytes类型转换为str类型
Sep 27 Python
PyCharm+PySpark远程调试的环境配置的方法
Nov 29 Python
Python设计模式之代理模式实例详解
Jan 19 Python
基于python的docx模块处理word和WPS的docx格式文件方式
Feb 13 Python
python opencv 检测移动物体并截图保存实例
Mar 10 Python
Django实现图片上传功能步骤解析
Apr 22 Python
Python如何操作docker redis过程解析
Aug 10 Python
详解Python中string模块除去Str还剩下什么
Nov 30 Python
Python面向对象之内置函数相关知识总结
Jun 24 Python
Python Matplotlib绘制条形图的全过程
Oct 24 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
php 数学运算验证码实现代码
2009/10/11 PHP
php cout&amp;lt;&amp;lt;的一点看法
2010/01/24 PHP
ThinkPHP之用户注册登录留言完整实例
2014/07/22 PHP
PHP实现的登录页面信息提示功能示例
2017/07/24 PHP
PHP框架Laravel中使用UUID实现数据分表操作示例
2018/05/30 PHP
Javascript-Mozilla和IE中的一个函数直接量的问题
2007/01/09 Javascript
JavaScript 类的定义和引用 JavaScript高级培训 自定义对象
2010/04/27 Javascript
实现点击列表弹出列表索引的两种方式
2013/03/08 Javascript
JavaScript控制浏览器全屏及各种浏览器全屏模式的方法、属性和事件
2015/12/20 Javascript
jQuery添加options点击事件并传值实例代码
2016/05/18 Javascript
深入理解JQuery循环绑定事件
2016/06/02 Javascript
jQuery插件ajaxFileUpload异步上传文件
2016/10/19 Javascript
Ztree新增角色和编辑角色回显问题的解决
2016/10/25 Javascript
js实现单张图片平移切换效果
2017/10/11 Javascript
react native 获取地理位置的方法示例
2018/08/28 Javascript
VUE前端从后台请求过来的数据进行转换数据结构操作
2020/11/11 Javascript
Vue项目打包部署到apache服务器的方法步骤
2021/02/01 Vue.js
[53:23]Secret vs Liquid 2018国际邀请赛淘汰赛BO3 第二场 8.25
2018/08/29 DOTA
进一步探究Python的装饰器的运用
2015/05/05 Python
Django中URL视图函数的一些高级概念介绍
2015/07/20 Python
Python实现动态加载模块、类、函数的方法分析
2017/07/18 Python
python读取有密码的zip压缩文件实例
2019/02/08 Python
基于wxPython的GUI实现输入对话框(1)
2019/02/27 Python
一行Python代码过滤标点符号等特殊字符
2019/08/12 Python
Python使用字典实现的简单记事本功能示例
2019/08/15 Python
python实现超市商品销售管理系统
2019/10/25 Python
python3 BeautifulSoup模块使用字典的方法抓取a标签内的数据示例
2019/11/28 Python
python将四元数变换为旋转矩阵的实例
2019/12/04 Python
python 实现压缩和解压缩的示例
2020/09/22 Python
英国领先的新鲜松露和最好的松露产品供应商:TruffleHunter
2019/08/26 全球购物
澳大利亚在线批发商:Simply Wholesale
2021/02/24 全球购物
精伦电子Java笔试题
2013/01/16 面试题
大学军训自我鉴定
2013/12/15 职场文书
民族团结好少年事迹材料
2014/08/19 职场文书
最美家庭活动方案
2014/08/31 职场文书
2014年人大工作总结
2014/12/10 职场文书