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的几种开发工具介绍
Mar 07 Python
python网络编程之UDP通信实例(含服务器端、客户端、UDP广播例子)
Apr 25 Python
python实现进程间通信简单实例
Jul 23 Python
Python实现删除列表中满足一定条件的元素示例
Jun 12 Python
python selenium UI自动化解决验证码的4种方法
Jan 05 Python
Python的多维空数组赋值方法
Apr 13 Python
对python 数据处理中的LabelEncoder 和 OneHotEncoder详解
Jul 11 Python
利用Python求阴影部分的面积实例代码
Dec 05 Python
python树莓派红外反射传感器
Jan 21 Python
python_array[0][0]与array[0,0]的区别详解
Feb 18 Python
Keras中的多分类损失函数用法categorical_crossentropy
Jun 11 Python
使用scrapy ImagesPipeline爬取图片资源的示例代码
Sep 28 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
获取用户Ip地址通用方法与常见安全隐患(HTTP_X_FORWARDED_FOR)
2013/06/01 PHP
php实现删除空目录的方法
2015/03/16 PHP
基于Swoole实现PHP与websocket聊天室
2016/08/03 PHP
实例解析php的数据类型
2018/10/24 PHP
Thinkphp 框架扩展之Widget扩展实现方法分析
2020/04/23 PHP
[原创]保存的js无法执行的解决办法
2007/02/25 Javascript
javascript 同时在IE和FireFox获取KeyCode的代码
2010/02/07 Javascript
深入理解Javascript闭包 新手版
2010/12/28 Javascript
js出生日期 年月日级联菜单示例代码
2014/01/10 Javascript
jquery操作HTML5 的data-*的用法实例分享
2014/08/17 Javascript
JS使用cookie实现DIV提示框只显示一次的方法
2015/11/05 Javascript
js中window.open的参数及注意注意事项
2016/07/06 Javascript
基于js里调用函数时,函数名带括号和不带括号的区别
2016/07/28 Javascript
JS弹出新窗口被拦截的解决方法
2016/08/09 Javascript
jQuery 常见小例汇总
2016/12/14 Javascript
AngularJS 最常用的八种功能(基础知识)
2017/06/26 Javascript
详解如何用模块化的方式写vuejs
2017/12/16 Javascript
javascript中this的用法实践分析
2019/07/29 Javascript
vue.js路由mode配置之去掉url上默认的#方法
2019/11/01 Javascript
JavaScript undefined及null区别实例解析
2020/07/21 Javascript
Element-ui树形控件el-tree自定义增删改和局部刷新及懒加载操作
2020/08/31 Javascript
vue任意关系组件通信与跨组件监听状态vue-communication
2020/10/18 Javascript
[02:50]【扭转乾坤,只此一招】DOTA2永雾林渊版本开启新篇章
2020/12/22 DOTA
python下读取公私钥做加解密实例详解
2017/03/29 Python
详谈Python高阶函数与函数装饰器(推荐)
2017/09/30 Python
Python实现动态图解析、合成与倒放
2018/01/18 Python
Python装饰器原理与基本用法分析
2020/01/07 Python
python 使用事件对象asyncio.Event来同步协程的操作
2020/05/04 Python
轻松制作精彩视频:Animoto
2018/09/19 全球购物
酒店秘书求职信范文
2014/02/17 职场文书
大学生找工作求职信
2014/07/09 职场文书
2015年城管个人工作总结
2015/05/15 职场文书
2019如何书写演讲稿?
2019/07/01 职场文书
小程序教您怎样你零成本推广获取数万用户的方法
2019/07/30 职场文书
详解MongoDB的条件查询和排序
2021/06/23 MongoDB
MySQL实例精讲单行函数以及字符数学日期流程控制
2021/10/15 MySQL