为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

潇湘沐 2022-06-28 10:28:19
?我应该通过包含子字符串和两个可识别的字符模式来过滤字符串数组 *。?- 一个任意符号*- 任何数量的任何符号以数据为例,['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(但我不确定)或其他东西。
查看完整描述

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以获取完整参考。


查看完整回答
反对 回复 2022-06-28
?
陪伴而非守候

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']


查看完整回答
反对 回复 2022-06-28
?
慕妹3242003

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']


查看完整回答
反对 回复 2022-06-28
  • 3 回答
  • 0 关注
  • 283 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号