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 连连看连接算法
Nov 22 Python
python实现zencart产品数据导入到magento(python导入数据)
Apr 03 Python
python base64 decode incorrect padding错误解决方法
Jan 08 Python
介绍Python中的一些高级编程技巧
Apr 02 Python
在Mac OS上搭建Python的开发环境
Dec 24 Python
简单谈谈Python中的闭包
Nov 30 Python
VSCode Python开发环境配置的详细步骤
Feb 22 Python
flask框架自定义过滤器示例【markdown文件读取和展示功能】
Nov 08 Python
python中数字是否为可变类型
Jul 08 Python
用 python 进行微信好友信息分析
Nov 28 Python
pytorch实现ResNet结构的实例代码
May 17 Python
使用python求解迷宫问题的三种实现方法
Mar 17 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图形计数器程序显示网站用户浏览量
2016/07/20 PHP
php cookie 详解使用实例
2016/11/03 PHP
php制作基于xml的RSS订阅源功能示例
2017/02/08 PHP
php插件Xajax使用方法详解
2017/08/31 PHP
jquery cookie实现的简单换肤功能适合小网站
2013/08/25 Javascript
Eclipse去除js(JavaScript)验证错误
2014/02/11 Javascript
浅谈javascript中createElement事件
2014/12/05 Javascript
JavaScript实现表格点击排序的方法
2015/05/11 Javascript
JavaScript实现对下拉列表值进行排序的方法
2015/07/15 Javascript
jQuery Easyui 验证两次密码输入是否相等
2016/05/13 Javascript
Summernote实现图片上传功能的简单方法
2016/07/11 Javascript
AngularJS入门教程之双向绑定详解
2016/08/18 Javascript
vue v-on监听事件详解
2017/05/17 Javascript
vue中vee validate表单校验的几种基本使用
2018/06/25 Javascript
React Hooks的深入理解与使用
2018/11/12 Javascript
jquery简易手风琴插件的封装
2020/10/13 jQuery
[00:36]DOTA2上海特级锦标赛 Archon战队宣传片
2016/03/04 DOTA
Python对象的深拷贝和浅拷贝详解
2014/08/25 Python
Python字符串处理实现单词反转
2017/06/14 Python
解决python使用open打开文件中文乱码的问题
2017/12/29 Python
浅谈Pandas 排序之后索引的问题
2018/06/07 Python
Python爬取成语接龙类网站
2018/10/19 Python
对python读取zip压缩文件里面的csv数据实例详解
2019/02/08 Python
python 抓包保存为pcap文件并解析的实例
2019/07/23 Python
OpenCV里的imshow()和Matplotlib.pyplot的imshow()的实现
2019/11/25 Python
苏格兰在线威士忌商店:The Whisky Barrel
2019/05/07 全球购物
我的长生果教学反思
2014/04/28 职场文书
小学领导班子对照材料
2014/08/23 职场文书
我爱家乡演讲稿
2014/09/12 职场文书
2014年幼儿园德育工作总结
2014/12/17 职场文书
2015年发展党员工作总结报告
2015/03/31 职场文书
领导新年致辞2016
2015/07/29 职场文书
获奖感言怎么写
2015/07/31 职场文书
Ajax实现异步加载数据
2021/11/17 Javascript
vue如何使用模拟的json数据查看效果
2022/03/31 Vue.js
mysql序号rownum行号实现方式
2022/12/24 MySQL