使用python的glob.glob中的正则表达式

use*_*868 31 python glob

import glob

list = glob.glob(r'*abc*.txt') + glob.glob(r'*123*.txt') + glob.glob(r'*a1b*.txt')

for i in list:
  print i
Run Code Online (Sandbox Code Playgroud)

此代码用于列出当前文件夹中名称中包含"abc","123"或"a1b"的文件.如何使用一个glob来实现这个功能,谢谢

Sch*_*uki 49

最简单的方法是自己过滤glob结果.以下是使用简单循环理解的方法:

import glob
res = [f for f in glob.glob("*.txt") if "abc" in f or "123" in f or "a1b" in f]
for f in res:
    print f
Run Code Online (Sandbox Code Playgroud)

你也可以使用正则表达式而不是glob:

import os
import re
res = [f for f in os.listdir(path) if re.search(r'(abc|123|a1b).*\.txt$', f)]
for f in res:
    print f
Run Code Online (Sandbox Code Playgroud)

(顺便说一句,命名变量list是一个坏主意,因为它list是一个Python类型...)

  • res = [f for f in glob.glob("*.txt") if re.match(r'[abc|123|a1b].*', f) (3认同)
  • 我认为你的意思是"或"而不是"和",不是吗? (2认同)

sle*_*cal 12

基于其他答案,这是一种随时可用的方法.它不是最重要的性能,但它的工作原理如上所述;

def reglob(path, exp, invert=False):
    """glob.glob() style searching which uses regex

    :param exp: Regex expression for filename
    :param invert: Invert match to non matching files
    """

    m = re.compile(exp)

    if invert is False:
        res = [f for f in os.listdir(path) if m.search(f)]
    else:
        res = [f for f in os.listdir(path) if not m.search(f)]

    res = map(lambda x: "%s/%s" % ( path, x, ), res)
    return res
Run Code Online (Sandbox Code Playgroud)

  • 我更喜欢 lambda x: os.path.join(path,x) (2认同)
  • @user_na:更好的是,这应该在“res”列表理解中正确完成,而不是再次循环所有匹配项。 (2认同)

Eva*_*van 8

我很惊讶这里没有答案使用过滤器。

import os
import re

def glob_re(pattern, strings):
    return filter(re.compile(pattern).match, strings)

filenames = glob_re(r'.*(abc|123|a1b).*\.txt', os.listdir())
Run Code Online (Sandbox Code Playgroud)

这接受任何返回字符串的迭代器,包括列表,元组,字典(如果所有键都是字符串)等。如果要支持部分匹配,则可以更改.match.search。请注意,这显然会返回一个生成器,因此,如果您要使用结果而不对其进行迭代,则可以将结果自己转换为列表,或者将return语句包装为list(...)。

  • @argan python 中的各种操作都会延迟评估其结果,过滤器就是其中之一。延迟计算在您编写的实际程序中很有用,这是有技术原因的,但是当您在 repl 中进行交互编程时,它始终是烦恼的根源。我完全理解只需将其包装在一个列表中以进行交互式运行一次编码,但是当您不在单行代码的范围内时,最好利用惰性求值。 (3认同)