Python如何使用特殊符号搜索子字符串?和*(类似RexExp)
我应该为Python如何使用特殊符号搜索子字符串?和*(类似RexExp),python,regex,glob,Python,Regex,Glob,我应该为?和*包含子字符串和两个可识别的字符模式来过滤字符串数组 ?-任意一个符号 *-任意数量的任意符号 以数据为例,['baab'、'abbb'、'fc'、'AA']它的工作原理如下: '?b' -> ['baab', 'abbb'] '?a' -> ['baab'] 'c?' -> [] 'b??b' -> ['baab'] '???' -> ['baab', 'abbb'] 'b*b' -> ['baab', 'abbb'] '***' -> [
?
和*
包含子字符串和两个可识别的字符模式来过滤字符串数组
?
-任意一个符号
*
-任意数量的任意符号
以数据为例,['baab'、'abbb'、'fc'、'AA']
它的工作原理如下:
'?b' -> ['baab', 'abbb']
'?a' -> ['baab']
'c?' -> []
'b??b' -> ['baab']
'???' -> ['baab', 'abbb']
'b*b' -> ['baab', 'abbb']
'***' -> ['baab', 'abbb', 'fc', 'AA']
我不能在操作符中使用。
最简单的解决方法是什么?也许它应该是RegExp(但我不确定)或其他东西。正则表达式的方法是1)收缩所有连续的*
s,2)re.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)])
看
在这里,像?b***
这样的模式将被转换为(?s).b.*
模式,这意味着:
(?s)
-一个内联re.DOTALL
修饰符,也可以使
匹配换行符
-任意1个字符
b
-ab
char
*
-尽可能多的0+字符
如果您需要支持任何glob模式您需要接受glob模式的方法(这就是您的?
和*
在这里是通配符)
这里唯一的问题是,fnmatch
globs必须匹配整个输入,而您的模式是未编排的
因此,您需要使用*
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']
参见。正则表达式的方法是:1)收缩所有连续的*
s,2)re.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)])
看
在这里,像?b***
这样的模式将被转换为(?s).b.*
模式,这意味着:
(?s)
-一个内联re.DOTALL
修饰符,也可以使
匹配换行符
-任意1个字符
b
-ab
char
*
-尽可能多的0+字符
如果您需要支持任何glob模式您需要接受glob模式的方法(这就是您的?
和*
在这里是通配符)
这里唯一的问题是,fnmatch
globs必须匹配整个输入,而您的模式是未编排的
因此,您需要使用*
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']
请参阅。您应该使用正则表达式:
对于任何字符,使用一个点-
对于任意数量的字符,请使用一个点后跟一个星-
对于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']
查看完整的参考。您应该使用正则表达式:
对于任何字符,使用一个点-
对于任意数量的字符,请使用一个点后跟一个星-
对于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']
查看完整参考。您可以在可识别字符模式中用
替换“?”,用*?
替换
来修复模式,并返回至少只包含一个匹配项的子字符串(re.search
):
输出:
['baab', 'abbb']
['baab']
[]
['baab']
['baab', 'abbb']
['baab', 'abbb']
['baab', 'abbb', 'fc', 'AA']
您可以通过在可识别字符模式中将“?”替换为
并将*
替换为*?
来修复模式,并返回至少包含一个匹配项的任何子字符串(重新搜索
):
输出:
['baab', 'abbb']
['baab']
[]
['baab']
['baab', 'abbb']
['baab', 'abbb']
['baab', 'abbb', 'fc', 'AA']
我想说,***
应该抛出一个错误。在指定的次数内匹配无限数量的字符是没有意义的。或者,这些应该减少到1*
。@Wiktor Stribiżew我认为你完全正确,但我不是这个案例的任务制定者。好的,找到一个:import fnmatch
,然后fnmatch.filter(l,'*{}*'.format(你的ż模式))
。看,我会说,***
应该抛出一个错误。在指定的次数内匹配无限数量的字符是没有意义的。或者,这些应该减少到1*
。@Wiktor Stribiżew我认为你完全正确,但我不是这个案例的任务制定者。好的,找到一个:import fnmatch
,然后fnmatch.filter(l,'*{}*'.format(你的ż模式))
。不过,请参见fnmatch
也执行字符类和依赖操作系统的大小写规范化。这个问题听起来更像是家庭作业,而不是直接的shell globbing,因此字符类和大小写规范化可能是不需要的。@user2357112查看更新答案的顶部。这就是你的意思吗?不,因为现在可能有更多不需要的功能,比如正则表达式字符类和组,反斜杠转义等等。(此外,输入模式可能包含应按字面匹配的
字符。)fnmatch
也执行字符类和依赖操作系统的大小写规范化。这个问题听起来更像是家庭作业,而不是直接的shell globbing,因此字符类和大小写规范化可能是不需要的。@user2357112查看更新答案的顶部。这就是你的意思吗?不,因为现在可能有更多不需要的功能,比如正则表达式字符类和组,反斜杠转义等等。(此外,输入模式可能包含应按字面匹配的
字符。)