3 回答
TA贡献1804条经验 获得超7个赞
您应该使用正则表达式: 对于任何字符,使用一个点 - 对于任意数量的任何字符,使用一个点后跟一个星号 - 对于 0 或 1 个字符,使用一个点后跟一个问号。
import re
define shortlist (pattern, list):
return [s for s in list if re.search(pattern, s)]
mylist = ['baab', 'abbb', 'fc', 'AA']
l = shortlist('.b', mylist) # l = ['baab', 'abbb']
l = shortlist('.a', mylist) # l = ['baab']
l = shortlist('b..b', mylist) # l = ['baab']
l = shortlist('b.*b', mylist) # l = ['baab', 'abbb']
l = shortlist('.{3}', mylist) # l = ['baab', 'abbb']
查看https://docs.python.org/3/library/re.html以获取完整参考。
TA贡献1757条经验 获得超8个赞
您可以通过替换“?”来修复模式 with.和*with .*?in recognizable character patterns并返回substring至少包含一个匹配项 ( re.search) 的任何内容:
import re
example = ['baab', 'abbb', 'fc', 'AA']
def filter_by_pattern(elements, pattern):
# convert `?` and `*` flags
pattern = pattern.replace('?', '.').replace('*', '.*?')
# you could make this a generator instead of list if you like
return [substring for substring in elements if re.search(pattern, substring)]
print(filter_by_pattern(example , '?b'))
print(filter_by_pattern(example , '?a'))
print(filter_by_pattern(example , 'c?'))
print(filter_by_pattern(example , 'b??b'))
print(filter_by_pattern(example , '???' ))
print(filter_by_pattern(example , 'b*b' ))
print(filter_by_pattern(example , '***' ))
输出:
['baab', 'abbb']
['baab']
[]
['baab']
['baab', 'abbb']
['baab', 'abbb']
['baab', 'abbb', 'fc', 'AA']
TA贡献1824条经验 获得超6个赞
一种正则表达式方法是 1) 收缩所有连续*的 s,2)和3re.escape之间的部分3) 在使用修饰符编译正则表达式时用和替换每个:?**.*?.re.DOTALL
import re
def repl(m):
res = "{}{}".format(re.escape(m.group(1)), m.group(2).replace("*", ".*").replace("?", "."))
if m.group(3):
res += re.escape(m.group(3))
return res
def glob_to_regex(glob):
glob = re.sub(r'\*{2,}', '*', glob)
return '(?s)' + re.sub(r'([^?*]*)([*?]+)([^?*]+$)?', repl , glob)
l = ['baab', 'abbb', 'fc', 'AA', 'abb.']
print([x for x in l if re.search(glob_to_regex('?b*b'), x)])
print([x for x in l if re.search(glob_to_regex('?b*.'), x)])
请参阅Python 演示。
在这里,一个类似的模式?b***将被翻译成一个(?s).b.*模式,这意味着:
(?s)- 一个内联re.DOTALL修饰符,也使.匹配换行符.- 任何 1 个字符b- 一个b字符.*- 尽可能多的任何 0+ 字符。
如果您需要支持任何glob模式,则需要fnmatch.filter(names, pattern)接受glob模式的方法(这就是您的?和*在此处的通配符)。
这里的独特问题是,fnmatch当您的模式未锚定时,glob 必须匹配整个输入。
因此,您需要用*s 包装您的模式:
import fnmatch
l = ['baab', 'abbb', 'fc', 'AA']
print(fnmatch.filter(l, '*{}*'.format('?b')))
print(fnmatch.filter(l, '*{}*'.format('?a')))
print(fnmatch.filter(l, '*{}*'.format('c?')))
print(fnmatch.filter(l, '*{}*'.format('b??b')))
print(fnmatch.filter(l, '*{}*'.format('???')))
print(fnmatch.filter(l, '*{}*'.format('b*b')))
print(fnmatch.filter(l, '*{}*'.format('***')))
输出:
['baab', 'abbb']
['baab']
[]
['baab']
['baab', 'abbb']
['baab', 'abbb']
['baab', 'abbb', 'fc', 'AA']
添加回答
举报
