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 07 Python
Python中使用items()方法返回字典元素对的教程
May 21 Python
Python SQL查询并生成json文件操作示例
Aug 17 Python
Python 获取主机ip与hostname的方法
Dec 17 Python
python 读取文件并把矩阵转成numpy的两种方法
Feb 12 Python
python爬虫神器Pyppeteer入门及使用
Jul 13 Python
python代码编写计算器小程序
Mar 30 Python
python hashlib加密实现代码
Oct 17 Python
Jupyter Notebook输出矢量图实例
Apr 14 Python
Python利器openpyxl之操作excel表格
Apr 17 Python
python面向对象版学生信息管理系统
Jun 24 Python
Python中time标准库的使用教程
Apr 13 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读取30天之内的根据算法排序的代码
2008/04/06 PHP
PHP 常用数组内部函数(Array Functions)介绍
2013/06/05 PHP
关于php程序报date()警告的处理(date_default_timezone_set)
2013/10/22 PHP
php inc文件使用的风险和注意事项
2013/11/12 PHP
php中限制ip段访问、禁止ip提交表单的代码分享
2014/08/22 PHP
Thinkphp模板标签if和eq的区别和比较实例分析
2015/07/01 PHP
十个优秀的Ajax/Javascript实例网站收集
2010/03/31 Javascript
通过jquery还原含有rowspan、colspan的table的实现方法
2012/02/10 Javascript
js 代码优化点滴记录
2012/02/19 Javascript
jQuery ajax(复习)—Baidu ajax request分离版
2013/01/24 Javascript
JavaScript 处理Iframe自适应高度(同或不同域名下)
2013/03/29 Javascript
写JQuery插件的基本知识
2013/11/25 Javascript
可插入图片的TEXT文本框
2013/12/27 Javascript
jQuery实现自定义checkbox和radio样式
2015/07/13 Javascript
简单了解JavaScript操作XPath的一些基本方法
2016/06/03 Javascript
jQuery EasyUI 组件加上“清除”功能实例详解
2017/04/11 jQuery
Angular 4依赖注入学习教程之ClassProvider的使用(三)
2017/06/04 Javascript
node vue项目开发之前后端分离实战记录
2017/12/13 Javascript
17道题让你彻底理解JS中的类型转换
2019/08/08 Javascript
Java 生成随机字符的示例代码
2021/01/13 Javascript
python对指定目录下文件进行批量重命名的方法
2015/04/18 Python
使用Python来编写HTTP服务器的超级指南
2016/02/18 Python
python制作爬虫并将抓取结果保存到excel中
2016/04/06 Python
python3爬取各类天气信息
2018/02/24 Python
python爬取m3u8连接的视频
2018/02/28 Python
浅谈flask源码之请求过程
2018/07/26 Python
python命名空间(namespace)简单介绍
2019/08/10 Python
利用HTML5绘制点线面组成的3D图形的示例
2015/05/12 HTML / CSS
人力资源专员自我评价怎么写
2013/09/19 职场文书
工厂保洁员岗位职责
2013/12/04 职场文书
学生会干部自荐信
2014/02/04 职场文书
机关保密工作承诺书
2015/05/04 职场文书
2017大学生寒假社会实践心得体会
2016/01/14 职场文书
Java用自带的Image IO给图片添加水印
2021/06/15 Java/Android
关于Nginx中虚拟主机的一些冷门知识小结
2022/03/03 Servers
oracle delete误删除表数据后如何恢复
2022/06/28 Oracle