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 相关文章推荐
wxPython窗口中文乱码解决方法
Oct 11 Python
Python中的日期时间处理详解
Nov 17 Python
Python中模块string.py详解
Mar 12 Python
pandas DataFrame实现几列数据合并成为新的一列方法
Jun 08 Python
详解Python3序列赋值、序列解包
May 14 Python
pybind11和numpy进行交互的方法
Jul 04 Python
python实现视频读取和转化图片
Dec 10 Python
python获取引用对象的个数方式
Dec 20 Python
Python环境管理virtualenv&amp;virtualenvwrapper的配置详解
Jul 01 Python
python实现图书馆抢座(自动预约)功能的示例代码
Sep 29 Python
python爬虫破解字体加密案例详解
Mar 02 Python
python源文件的字符编码知识点详解
Mar 04 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
复杂检索数据并分页显示的处理方法
2006/10/09 PHP
PHP开发入门教程之面向对象
2006/12/05 PHP
php开发留言板的CRUD(增,删,改,查)操作
2012/04/19 PHP
php多文件上传实现代码
2014/02/20 PHP
PHP扩展模块Pecl、Pear以及Perl的区别
2014/04/09 PHP
php中隐形字符65279(utf-8的BOM头)问题
2014/08/16 PHP
PHP单文件上传原理及上传函数的封装操作示例
2019/09/02 PHP
TP5(thinkPHP5)框架使用ajax实现与后台数据交互的方法小结
2020/02/10 PHP
简洁短小的 JavaScript IE 浏览器判定代码
2010/03/21 Javascript
javascript 实现 秒杀,团购 倒计时展示的记录 分享
2013/07/12 Javascript
IE、FF浏览器下修改标签透明度
2014/01/28 Javascript
js中跨域方法原理详解
2015/07/19 Javascript
JavaScript 实现的 zip 压缩和解压缩工具包Zip.js使用详解
2015/12/14 Javascript
Bootstrap模仿起筷首页效果
2016/05/09 Javascript
jQuery soColorPacker 网页拾色器
2016/06/22 Javascript
Bootstrap 下拉多选框插件Bootstrap Multiselect
2017/01/22 Javascript
vue组件如何被其他项目引用
2017/04/13 Javascript
原生JS实现日历组件的示例代码
2017/09/22 Javascript
vue自定义过滤器创建和使用方法详解
2017/11/06 Javascript
node的process以及child_process模块学习笔记
2018/03/06 Javascript
[44:40]2018DOTA2亚洲邀请赛3月30日 小组赛A组Liquid VS OG
2018/03/31 DOTA
python实现从一组颜色中找出与给定颜色最接近颜色的方法
2015/03/19 Python
matplotlib 纵坐标轴显示数据值的实例
2018/05/25 Python
Python基于OpenCV库Adaboost实现人脸识别功能详解
2018/08/25 Python
浅析Python四种数据类型
2018/09/26 Python
Python的条件表达式和lambda表达式实例
2019/01/31 Python
Python实现的爬取豆瓣电影信息功能案例
2019/09/15 Python
Pytorch数据拼接与拆分操作实现图解
2020/04/30 Python
基于python实现ROC曲线绘制广场解析
2020/06/28 Python
手对手的教你用canvas画一个简单的海报的方法示例
2018/12/10 HTML / CSS
数控技术应用个人求职信范文
2014/02/03 职场文书
交通事故私了协议书
2014/04/16 职场文书
关于梦想的演讲稿
2014/05/05 职场文书
Pytorch 如何实现LSTM时间序列预测
2021/05/17 Python
Python实现视频中添加音频工具详解
2021/12/06 Python
Java9新特性之Module模块化编程示例演绎
2022/03/16 Java/Android