Python下类Shell通配符匹配字符串
时间:2022-07-24
本文章向大家介绍Python下类Shell通配符匹配字符串,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
如果你想Python下跟Shell下一样,使用通配符来做字符串的匹配,例如: *.py
, nginx-access-2018060[0-9]*.log
等。
在Python下可以利用fnmatch
提供的两个函数fnmatch()
和 fnmatchcase()
来实现这种类Shell下通配符匹配的情况,源码分别如下:
fnmatch
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 seqAn 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)
fnmatchcase
@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).matchdef 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
简单示例如下:
>>> from fnmatch import fnmatch, fnmatchcase
>>> fnmatch('hello.py', '*.py')
True
>>> fnmatch('hello.py', '?ello.py')
True
>>> fnmatch('nginx-access-20180609.log', 'nginx-access-2018060[0-9]*')
True
>>> fnmatch('nginx-access-20180609.log', 'nginx-access-2018060[0-9].log')
True
>>> file_names = ['nginx-access-20180620.log', 'hello.py', 'config.ini', 'sendData.py']
>>> [name for name in file_names if fnmatch(name, '*.py')]
['hello.py', 'sendData.py']
但是有一个问题fnmatch()
函数在不同底层操作系统下使用的时候对大小写敏感, 不同的系统表现情况不同,如下所示:
>>> # On OS X (Mac)
>>> fnmatch('test.txt', '*.TXT')
False
>>> # On Windows
>>> fnmatch('test.txt', '*.TXT')
True
>>>
如果你对这个区别很在意,可以使用fnmatchcase()
来代替, 它会严格按照大小写来匹配,如下示例:
>>> fnmatchcase('test.txt', '*.TXT')
False
>>> fnmatchcase('test.txt', '*.txt')
True
这两个函数通常还有一个会被忽略的一个特性是在处理非文件名的字符串时候它们也是很有用的。 比如,假设你有一个街道地址的列表数据:
addresses = [
'5412 N CLARK ST',
'1060 W ADDISON ST',
'1039 W GRANVILLE AVE',
'2122 N CLARK ST',
'4802 N BROADWAY',
]
你可以如下这样写列表推导式:
>>> from fnmatch import fnmatchcase
>>> [addr for addr in addresses if fnmatchcase(addr, '* ST')]
['5412 N CLARK ST', '1060 W ADDISON ST', '2122 N CLARK ST']
>>> [addr for addr in addresses if fnmatchcase(addr, '54[0-9][0-9] *CLARK*')]
['5412 N CLARK ST']
fnmatch()
函数匹配能力介于简单的字符串方法和强大的正则表达式之间。 如果在数据处理操作中只需要简单的通配符就能完成的时候, 使用它是一个很好的选择。
如果你的代码需要做文件名的匹配,最好使用glob
模块, 简单示例如下:
[root@nock opt]# pwd
/opt
[root@nock opt]# ls
file1.py file2.py file3.py file4.py
[root@nock opt]# python
Python 3.5.1 (default, Nov 20 2015, 02:00:19)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import glob
>>> pyfiles = glob.glob('/opt/*.py')
>>> pyfiles
['/opt/file1.py', '/opt/file2.py', '/opt/file3.py', '/opt/file4.py']
如果使用fnmatch()
函数,操作如下:
>>> import os
>>> from fnmatch import fnmatch
>>> pyfiles = [name for name in os.listdir('/opt/') if fnmatch(name, '*.py')]
>>> pyfiles
['file1.py', 'file2.py', 'file3.py', 'file4.py']
如上示例我们可以看出来效果是一样的,但是你会发现使用glob
模块会更简单明了。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android实现动态改变app图标的示例代码
- 浅谈Android 的线程和线程池的使用
- 点餐系统的部署,Java点餐系统部署到腾讯云Linux服务器
- 详解Android 中AsyncTask 的使用
- 解决Android应用冷启动时出现的白屏问题的方法
- Java点餐系统+扫码点餐小程序部署文档(2020版)
- Android开发实现各种图形绘制功能示例
- Android webview手动校验https证书(by 星空武哥)
- AndroidStudio Gradle第三依赖统一管理的实现方法
- 小程序上传多张图片到springboot后台,返回可供访问的图片链接
- AndroidStudio Gradle基于友盟的多渠道打包方法
- Android开发之全屏与非全屏的切换设置方法小结
- Android使用GridView实现日历的方法
- Android控件AppWidgetProvider使用方法详解
- R语言使用链梯法Chain Ladder和泊松定律模拟和预测未来赔款数据