一说起通配符,大家非常快就会想起*和?

号,有了通配符,使得表达能力大大增强,非常多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的更多相关文章

  1. 飘逸的python - 性能调优利器profile及其意义

    VIM 的作者Bram Moolenaar在一篇叫高效文本编辑器的7个习惯的ppt中有这么一段话. Three basic steps 1.    Detect inefficiency 2.    ...

  2. 飘逸的python - __new__、__init__、__call__傻傻分不清

    __new__: 对象的创建,是一个静态方法.第一个參数是cls.(想想也是,不可能是self,对象还没创建,哪来的self) __init__ : 对象的初始化, 是一个实例方法,第一个參数是sel ...

  3. Python:glob

    学习自: (1)Python标准库glob模块_lianghe77的博客-CSDN博客_glob库 (2)Python:glob与os.listdir_鳄鱼的博客-CSDN博客 (3)python文件 ...

  4. python fnmatch & glob

    1,转载:Python模块学习 - fnmatch & glob - Dahlhin - 博客园 (cnblogs.com) 介绍 fnmatch 和 glob 模块都是用来做字符串匹配文件名 ...

  5. python 编程的 Style Guide

    Python 的作者既优雅又高冷又 鬼毛的 再 PEP8 里规定了 Python 程序编写规范.(风格和格式) 一.基本观念 1.可读性之上,代码被读的次数肯定比被写的次数多.因此作者十分重视代码的可 ...

  6. 飘逸的python - 增强的格式化字符串format函数

    自python2.6开始,新增了一种格式化字符串的函数str.format(),可谓威力十足.那么,他跟之前的%型格式化字符串相比,有什么优越的存在呢?让我们来揭开它羞答答的面纱. 语法 它通过{}和 ...

  7. 【leetcode❤python】 290. Word Pattern

    #-*- coding: UTF-8 -*-class Solution(object):    def wordPattern(self, pattern, str):        "& ...

  8. 飘逸的python - 编码杂症之在字符串前面加u

      有时候我们从其它地方接受的字符串经过艰难跋涉,它变了个样.比如收到的是'\u6253\u602a\u8005'而不是u'\u6253\u602a\u8005'. 明明肉眼看起来只需要加个u,但是怎 ...

  9. google python/c++ code style naming

    python: Guidelines derived from Guido's Recommendations Type Public Internal Packages lower_with_und ...

随机推荐

  1. Saiku导出excel指标列无线条以及0与空值显示问题(三十二)

    Saiku导出excel指标列无线条以及0与空值显示问题 描述: 数据库中字段值为0 ,与数据库中字段值为 null 时 ,saiku会将为0 以及为 null 的数据都不展示出来,但是我们其实希望数 ...

  2. 修路方案 Kruskal 之 次小生成树

    次小生成树 : Kruskal 是先求出来  最小生成树 , 并且记录下来所用到的的边 , 然后再求每次都 去掉最小生成树中的一个边 , 这样求最小生成树 , 然后看能不能得到 和原来最小生成树一样的 ...

  3. $P5017 摆渡车$

    problem 毒瘤\(DP\) #ifdef Dubug #endif #include <bits/stdc++.h> using namespace std; typedef lon ...

  4. Android 使用WebView浏览有声音或者视频的网页,关闭WebView之后,声音或者视频不停止的解决办法

    笔者最近使用Eclipse开发Android移动应用app,其实有一个功能是使用Android系统自带的WebView控件加载Web页面.开发很顺利,浏览也很正常.不过有个比较特殊的一点就是加载的We ...

  5. SQL练习题_用户购买收藏记录合并(拼多多)

    目录 拼多多笔试题0805_统计用户数据 笔试题描述 表格构建 数据观察 题目分析 一.合并表格 二.CASE表示(0,1) 三.同理复制FORK表 题目解答 拼多多笔试题0805_统计用户数据 笔试 ...

  6. JS高级——闭包练习

    从上篇文章我们知道与浏览器的交互操作如鼠标点击,都会被放入任务队列中,而放入到任务队列中是必须等到主线程的任务都执行完之后才能执行,故而我们有时利用for循环给dom注册事件时候,难以获取for循环中 ...

  7. C#——反射动态创建类的实例

    “反射”其实就是利用程序集的元数据信息. 反射可以有很多方法,编写程序时请先导入 System.Reflection 命名空间. 若要反射当前项目中的类(即当前项目已经引用它了),可以使用下面的写法. ...

  8. eclipse安装python开发pydev插件

    eclipse安装python开发pydev插件 下载eclipse的python开发插件pydev http://pan.baidu.com/s/1qXHt8pI 下载python.exe,并安装. ...

  9. Tomcat8 连接池

    1.所有的tomcat项目共用一个连接池配置 1.1 修改conf->context.xml文件,在Context节点下配置 <Resource name="jdbc/myDat ...

  10. (转)淘淘商城系列——初始SolrCloud

    http://blog.csdn.net/yerenyuan_pku/article/details/72944611 本文我只是简单介绍一下SolrCloud,如果大家要是感兴趣的话,可以参考Sol ...