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 面向对象 成员的访问约束
Dec 23 Python
Python多线程编程(五):死锁的形成
Apr 05 Python
在GitHub Pages上使用Pelican搭建博客的教程
Apr 25 Python
Python 爬虫学习笔记之多线程爬虫
Sep 21 Python
python 截取 取出一部分的字符串方法
Mar 01 Python
python实现感知器算法详解
Dec 19 Python
Python多进程与服务器并发原理及用法实例分析
Aug 21 Python
python 对给定可迭代集合统计出现频率,并排序的方法
Oct 18 Python
通过pykafka接收Kafka消息队列的方法
Dec 27 Python
关于Tensorflow分布式并行策略
Feb 03 Python
Python3爬虫里关于Splash负载均衡配置详解
Jul 10 Python
python基础之while循环语句的使用
Apr 20 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+mcDropdown实现文件路径可在下拉框选择
2013/08/07 PHP
PHP上传图片进行等比缩放可增加水印功能
2014/01/13 PHP
一组PHP可逆加密解密算法实例代码
2014/01/21 PHP
php使用百度天气接口示例
2014/04/22 PHP
php实现的双色球算法示例
2017/06/20 PHP
Laravel框架实现简单的学生信息管理平台案例
2019/05/07 PHP
jQuery旋转插件—rotate支持(ie/Firefox/SafariOpera/Chrome)
2013/01/16 Javascript
原生js和jquery中有关透明度设置的相关问题
2014/01/08 Javascript
jquery JSON的解析方式示例介绍
2014/07/27 Javascript
jQuery中ajax的get()方法用法实例
2014/12/26 Javascript
javascript实现全角与半角字符的转换
2015/01/07 Javascript
AngularJS学习笔记之依赖注入详解
2016/05/16 Javascript
jQuery 利用$.ajax 时获取原生XMLHttpRequest 对象的方法
2016/08/25 Javascript
微信小程序 wxapp地图 map详解
2016/10/31 Javascript
jQuery中Datatables增加跳转到指定页功能
2017/02/08 Javascript
通过npm引用的vue组件使用详解
2017/03/02 Javascript
vue使用rem实现 移动端屏幕适配
2018/09/26 Javascript
vue-router 路由传参用法实例分析
2020/03/06 Javascript
Vue和React有哪些区别
2020/09/12 Javascript
python实现猜数字游戏(无重复数字)示例分享
2014/03/29 Python
Python获取Linux系统下的本机IP地址代码分享
2014/11/07 Python
Python使用面向对象方式创建线程实现12306售票系统
2015/12/24 Python
对python模块中多个类的用法详解
2019/01/10 Python
Python3分析处理声音数据的例子
2019/08/27 Python
Python字节单位转换实例
2019/12/05 Python
python多进程并发demo实例解析
2019/12/13 Python
Python创建临时文件和文件夹
2020/08/05 Python
HTML5对比HTML4的主要改变和改进总结
2016/05/27 HTML / CSS
阿提哈德航空官方网站:Etihad Airways
2017/01/06 全球购物
巴西宠物商店:Cobasi
2019/04/19 全球购物
50道外企软件测试面试题
2014/08/18 面试题
学习雷锋做美德少年寄语大全
2014/04/09 职场文书
党的生日演讲稿
2014/09/10 职场文书
同意转租证明
2015/06/24 职场文书
毕业生求职自荐信(2016最新版)
2016/01/28 职场文书