猿问

Python如何使用特殊符号搜索子字符串?和 *(类似 RexExp)

?我应该通过包含子字符串和两个可识别的字符模式来过滤字符串数组 *。


?- 一个任意符号


*- 任何数量的任何符号


以数据为例,['baab', 'abbb', 'fc', 'AA']它应该如下工作:


'?b' -> ['baab', 'abbb']

'?a' -> ['baab']

'c?' -> []

'b??b' -> ['baab']

'???' -> ['baab', 'abbb']

'b*b' -> ['baab', 'abbb']

'***' -> ['baab', 'abbb', 'fc', 'AA']

我不能使用in运算符。最简单的解决方法是什么?也许它应该是 RegExp(但我不确定)或其他东西。


潇湘沐
浏览 284回答 3
3回答

三国纷争

您应该使用正则表达式: 对于任何字符,使用一个点 - 对于任意数量的任何字符,使用一个点后跟一个星号 - 对于 0 或 1 个字符,使用一个点后跟一个问号。import redefine 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以获取完整参考。

陪伴而非守候

您可以通过替换“?”来修复模式 with.和*with .*?in recognizable character patterns并返回substring至少包含一个匹配项 ( re.search) 的任何内容:import reexample = ['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']

慕妹3242003

一种正则表达式方法是 1) 收缩所有连续*的 s,2)和3re.escape之间的部分3) 在使用修饰符编译正则表达式时用和替换每个:?**.*?.re.DOTALLimport redef 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 resdef 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 fnmatchl = ['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']
随时随地看视频慕课网APP

相关分类

Python
我要回答