飘逸的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 ...
随机推荐
- python值函数名的使用以及闭包,迭代器
一.函数名的运用 函数名就是一个变量名,但它是一个特殊的变量名,是一个后面加括号可以执行函数的变量名. def func(): print("我是一个小小的函数") a = fun ...
- TCP协议滑动窗口(一)——控制大批量数据传输速率
窗口大小:TCP头中一个16位的域,表示当前可用接受缓冲区大小.在每个TCP对等段连接初始化时,告诉对方自己的窗口大小(不一定是满额,假如满额65201字节,可能暂时通告5840字节).若客户端接受数 ...
- Gradle的属性Property设置与调用
Gradle在默认情况下已经为Project定义了很多Property: project:Project本身 name:Project的名字 path:Project的绝对路径 description ...
- ARM架构与体系学习(二)——3级流水线
ARM架构与体系学习(二)——3级流水线 标签: 存储嵌入式汇编c 2012-04-18 00:44 5414人阅读 评论(4) 收藏 举报 分类: ARM7(16) 版权声明:本文为博主原创文章 ...
- zepto处理touch事件
处理Touch事件能让你了解到用户的每一根手指的位置,在touch事件触发的时候产生,可以通过touch event handler的event对象取到,如果基于zepto.js开发,一般是通过eve ...
- Java中字符串的常用属性与方法
•字符串常用的属性 string.length()————>返回字符串的长度,int类型. •字符串常用的方法 String.contains(";")——————>判 ...
- ceph部署
一.部署准备: 准备5台机器(linux系统为centos7.6版本),当然也可以至少3台机器并充当部署节点和客户端,可以与ceph节点共用: 1台部署节点(配一块硬盘,运行ceph-depo ...
- select 如何将文本居中
开始测试了几种方式但是结果都是失败的,最后测试一种方式终于成功了,所以做下笔记: select{ width: 3.2rem; height: 1.2rem; border-radius: 0.6re ...
- Linux:安装CentOS 6.x和CentOS 7.x
1,准备镜像,这里到阿里云镜像网站下载 https://opsx.alibaba.com/mirror 2,安装CentOS6.10 打开vmware workstation--> 典型--&g ...
- 13.multi_match实现dis_max+tie_breaker
主要知识点: 基于multi_match语法实现dis_max+tie_breaker 1.best_fields+tie_breaker GET /forum/article/_search ...