首页 > 编程 > Python > 正文

Python中fnmatch模块的使用详情

2020-02-15 23:52:00
字体:
来源:转载
供稿:网友

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 regularexpression. They cache the compiled regular expressions for speed.The function translate(PATTERN) returns a regular expressioncorresponding to PATTERN. (It does not compile it.)"""import osimport posixpathimport reimport 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).matchdef 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 resultdef 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 Nonedef 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            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表