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生成指定尺寸缩略图的示例
May 07 Python
Python使用metaclass实现Singleton模式的方法
May 05 Python
Flask框架的学习指南之用户登录管理
Nov 20 Python
python音频处理用到的操作的示例代码
Oct 27 Python
Python自定义装饰器原理与用法实例分析
Jul 16 Python
Python之pymysql的使用小结
Jul 01 Python
浅析python中while循环和for循环
Nov 19 Python
解决os.path.isdir() 判断文件夹却返回false的问题
Nov 29 Python
Python数据可视化图实现过程详解
Jun 12 Python
关于Theano和Tensorflow多GPU使用问题
Jun 19 Python
Python 利用argparse模块实现脚本命令行参数解析
Dec 28 Python
python中的列表和元组区别分析
Dec 30 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中DOMElement操作xml文档实例演示
2013/03/26 PHP
php empty()与isset()区别的详细介绍
2013/06/17 PHP
测试php函数的方法
2013/11/13 PHP
Yii框架实现邮箱激活的方法【数字签名】
2016/10/18 PHP
PHP+redis实现微博的推模型案例分析
2019/07/10 PHP
Thinkphp 框架扩展之驱动扩展实例分析
2020/04/27 PHP
SWFObject 2.1以上版本语法介绍
2010/07/10 Javascript
自用js开发框架小成 学习js的朋友可以看看
2010/11/16 Javascript
jQuery 中使用JSON的实现代码
2011/12/01 Javascript
基于jQuery的遍历同id元素 并响应事件的代码
2012/06/14 Javascript
javascript实现信息的显示和隐藏如注册页面
2013/12/03 Javascript
javascript中DOM复选框选择用法实例
2015/05/14 Javascript
详解js运算符单竖杠“|”与“||”的用法和作用介绍
2016/11/04 Javascript
jQuery插件FusionCharts实现的MSBar2D图效果示例【附demo源码】
2017/03/24 jQuery
JavaScript基本语法_动力节点Java学院整理
2017/06/26 Javascript
ECMAscript 变量作用域总结概括
2017/08/18 Javascript
js 获取json数组里面数组的长度实例
2017/10/31 Javascript
React组件中的this的具体使用
2018/02/28 Javascript
vue click.stop阻止点击事件继续传播的方法
2018/09/04 Javascript
基于nodejs的雪碧图制作工具的示例代码
2018/11/05 NodeJs
jQuery实现的简单日历组件定义与用法示例
2018/12/24 jQuery
vue使用echarts图表自适应的几种解决方案
2020/12/04 Vue.js
python使用post提交数据到远程url的方法
2015/04/29 Python
Python使用Paramiko模块编写脚本进行远程服务器操作
2016/05/05 Python
利用Python3分析sitemap.xml并抓取导出全站链接详解
2017/07/04 Python
Python 机器学习库 NumPy入门教程
2018/04/19 Python
Windows上使用Python增加或删除权限的方法
2018/04/24 Python
一行python实现树形结构的方法
2019/08/09 Python
如何解决安装python3.6.1失败
2020/07/01 Python
HTML5 本地存储实现购物车功能
2017/09/07 HTML / CSS
网易微博Web App用HTML5开发的过程介绍
2012/06/13 HTML / CSS
授权委托书公证
2014/09/14 职场文书
2016读书月活动心得体会
2016/01/14 职场文书
毕业季聚会祝酒词!
2019/07/04 职场文书
Python实现随机生成迷宫并自动寻路
2021/06/13 Python
Vue router配置与使用分析讲解
2022/12/24 Vue.js