飘逸的python - 实现glob style pattern
一说起通配符,大家非常快就会想起*和?
号,有了通配符,使得表达能力大大增强,非常多linux命令都支持这个东西,事实上就是glob style pattern.
就连redis的keys命令都支持glob.
我要实现的glob,支持下面特性:
- 星号*匹配0个或多个随意字符
- ?
匹配确切的一个随意字符
- [characters]匹配随意一个方括号内的字符,比方[abc],要么匹配a,要么匹配b,要么匹配c.
- [!character]排除方括号内的字符
- [character-character],表示2个字符范围内的都能够匹配,如[a-z],[0-9]
实现这个东西事实上挺简单的,从左往右扫描s串和p串,假设最后都走到了结尾,那么就是能够匹配的.
主要难点在于*号的匹配.由于*号能够匹配0个或者多个,所以须要试探回溯.这里通过保存*号位置,假设后面的走不通了,就拉回*号位置,贪婪匹配.
至于方括号的展开,弄个include和exclude变量就非常清晰了.
以下上代码.
#coding=utf-8
def build_expand(p):#方括号展开
ptr2include = {}
ptr2exclude = {}
ptr2next = {}
len_p = len(p)
pPtr = 0
while pPtr<len_p:
if p[pPtr] == '[':
start = pPtr
pPtr += 1
include = set([])
exclude = set([])
while p[pPtr]!=']':
if p[pPtr]=='!':
exclude.add(p[pPtr+1])
pPtr += 2
elif p[pPtr+1] == '-':
include.update({chr(x) for x in range(ord(p[pPtr]),ord(p[pPtr+2])+1)})
pPtr += 3
else:
include.add(p[pPtr])
pPtr += 1
if include:
ptr2include[start] = include
if exclude:
ptr2exclude[start] = exclude
ptr2next[start] = pPtr + 1
else:
pPtr += 1
return ptr2include, ptr2exclude, ptr2next def isMatch(s, p):
len_s = len(s); len_p = len(p)
sPtr = pPtr = ss = 0
star = None
ptr2include, ptr2exclude, ptr2next = build_expand(p)
while sPtr<len_s:
if pPtr<len_p and (p[pPtr] in ['?',s[sPtr]]):
sPtr += 1; pPtr += 1
continue
if pPtr<len_p and p[pPtr] == '[':
if pPtr in ptr2include and s[sPtr] in ptr2include[pPtr]:
sPtr += 1
pPtr = ptr2next[pPtr]
continue
if pPtr in ptr2exclude and s[sPtr] not in ptr2exclude[pPtr]:
sPtr += 1
pPtr = ptr2next[pPtr]
continue
if pPtr<len_p and p[pPtr]=='*':
star = pPtr; pPtr += 1; ss = sPtr
continue
if star is not None:
pPtr = star + 1; ss += 1; sPtr = ss
continue
return False
while pPtr<len(p) and p[pPtr]=='*':
pPtr += 1
return pPtr == len_p if __name__ == '__main__':
params = [
("aa","a"),
("aa","aa"),
("aaa","aa"),
("aa", "*"),
("aa", "a*"),
("ab", "?*"),
("aab", "c*a*b"),
("cab", "c*a*b"),
("cxyzbazba", "c*ba"),
('abc','ab[a-c]'),
('abd','ab[a-c]'),
('abe','ab[cde]'),
('abe','ab[!e]'),
('abe','ab[!c]'),
] for p in params:
print p,isMatch(*p)
执行结果是
('aa', 'a') False
('aa', 'aa') True
('aaa', 'aa') False
('aa', '*') True
('aa', 'a*') True
('ab', '?
*') True
('aab', 'c*a*b') False
('cab', 'c*a*b') True
('cxyzbazba', 'c*ba') True
('abc', 'ab[a-c]') True
('abd', 'ab[a-c]') False
('abe', 'ab[cde]') True
('abe', 'ab[!e]') False
('abe', 'ab[!c]') True
飘逸的python - 实现glob style pattern的更多相关文章
- 飘逸的python - 性能调优利器profile及其意义
VIM 的作者Bram Moolenaar在一篇叫高效文本编辑器的7个习惯的ppt中有这么一段话. Three basic steps 1. Detect inefficiency 2. ...
- 飘逸的python - __new__、__init__、__call__傻傻分不清
__new__: 对象的创建,是一个静态方法.第一个參数是cls.(想想也是,不可能是self,对象还没创建,哪来的self) __init__ : 对象的初始化, 是一个实例方法,第一个參数是sel ...
- Python:glob
学习自: (1)Python标准库glob模块_lianghe77的博客-CSDN博客_glob库 (2)Python:glob与os.listdir_鳄鱼的博客-CSDN博客 (3)python文件 ...
- python fnmatch & glob
1,转载:Python模块学习 - fnmatch & glob - Dahlhin - 博客园 (cnblogs.com) 介绍 fnmatch 和 glob 模块都是用来做字符串匹配文件名 ...
- python 编程的 Style Guide
Python 的作者既优雅又高冷又 鬼毛的 再 PEP8 里规定了 Python 程序编写规范.(风格和格式) 一.基本观念 1.可读性之上,代码被读的次数肯定比被写的次数多.因此作者十分重视代码的可 ...
- 飘逸的python - 增强的格式化字符串format函数
自python2.6开始,新增了一种格式化字符串的函数str.format(),可谓威力十足.那么,他跟之前的%型格式化字符串相比,有什么优越的存在呢?让我们来揭开它羞答答的面纱. 语法 它通过{}和 ...
- 【leetcode❤python】 290. Word Pattern
#-*- coding: UTF-8 -*-class Solution(object): def wordPattern(self, pattern, str): "& ...
- 飘逸的python - 编码杂症之在字符串前面加u
有时候我们从其它地方接受的字符串经过艰难跋涉,它变了个样.比如收到的是'\u6253\u602a\u8005'而不是u'\u6253\u602a\u8005'. 明明肉眼看起来只需要加个u,但是怎 ...
- google python/c++ code style naming
python: Guidelines derived from Guido's Recommendations Type Public Internal Packages lower_with_und ...
随机推荐
- JVM-垃圾回收器
目录 垃圾收集器 Serial收集器 Serial Old 收集器 ParNew 收集器 Parallel Scavenge 收集器 (并行清除) /'pærəlɛl/ /'skævɪndʒ/ Par ...
- mysql中判断记录是否存在方法
以下这个方法是我推荐的. sql语句:select 1 from tablename where col = col limit 1; 然后读取语句执行所影响的行数. 当然这里limit 1很重要.这 ...
- scrapy的UA池和代理池
一.下载中间件(Downloader Middlewares) 框架图如下 下载中间件(Downloader Middlewares)位于scrapy引擎和下载器之间的一层组件. - 作用: (1)引 ...
- html 基础演示代码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...
- No operations allowed after connection closed--转
https://www.jianshu.com/p/1626d41572f2 Spring boot的单数据源配置比较简单,只需要在application.properties配置相关的jdbc连接的 ...
- DataTable And DataRow
/// <summary> /// 将DataTable的字段名全部翻译为中文 /// </summary> /// <param name="table&qu ...
- 服务器端 CentOS 下配置 JDK 和 Tonmcat 踩坑合集
一.配置 JDK 时,在 /etc/profile 文件下配置环境变量,添加 #java environment export JAVA_HOME=/usr/java/jdk- export CL ...
- MVC5+EasyUI+EF6+Linq通用权限系统出炉(1)
1.先晒一下结构吧,
- 【技术累积】【点】【java】【30】代理模式
基础 代理模式是Java常见的设计模式之一.所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象. 什么是代理 参考现实生活中的代理 比如某个品牌的某个省的代理商,作 ...
- 解决richfaces自带的jquery
项目里有个有史以来让人头疼的问题,就是前端的richfaces框架自带有jquery插件,而且好像总是在最后才加载,导致前面自己加载好的jquery版本的框架以及应用到jquery的其他前端框架生成的 ...