python中的通配符列表匹配
我有一个字符串列表python中的通配符列表匹配,python,Python,我有一个字符串列表 l = [ '/api/users/*', '/api/account/* ] 道路就像 /api/users/add/ /api/users/edit/1 /api/users/ /api/account/view/1 /api/account/ 如果路径存在于列表l中,如何对路径执行筛选 状况 '/api/users/add/' in l 对于上述所有给定路径,应返回True l = [ '/api/users/*', '/api/accou
l = [
'/api/users/*',
'/api/account/*
]
道路就像
/api/users/add/
/api/users/edit/1
/api/users/
/api/account/view/1
/api/account/
如果路径存在于列表l
中,如何对路径执行筛选
状况
'/api/users/add/' in l
对于上述所有给定路径,应返回True
l = [
'/api/users/*',
'/api/account/'
]
paths = [
'/api/users/add/'
'/api/users/edit/1',
'/api/users/',
'/api/account/view/1',
'/api/account/'
]
for path in paths:
if path in l:
print("Path: {}, found in the list".format(path))
输出:
Path: /api/account/, found in the list
False
False
False
False
True
False
False
True
False
True
编辑:
如果需要返回布尔值的方法:
l = [
'/api/users/*',
'/api/account/'
]
paths = [
'/api/users/add/',
'/api/users/edit/1',
'/api/users/',
'/api/account/view/1',
'/api/account/'
]
def checkPath(path):
if path in l:
return True
else:
return False
for i in range(0,len(paths)):
print(checkPath(paths[i]))
输出:
Path: /api/account/, found in the list
False
False
False
False
True
False
False
True
False
True
编辑2:
如果希望*
与路径匹配,可以从原始列表中删除*
,然后进行如下迭代:
def checkPath(path):
if path in l_new:
return True
else:
return False
# strip the asterick
l_new = [s.strip('*') for s in l]
for i in range(0,len(paths)):
print(checkPath(paths[i]))
输出:
Path: /api/account/, found in the list
False
False
False
False
True
False
False
True
False
True
或列表:
print('\n'.join(['Path: {}, found in the list'.format(path) for path in paths if path in l]))
您可以使用正则表达式将路径模式末尾的
*
替换为*
,然后将它们本身用作正则表达式以匹配列表中的路径
paths = ['/api/users/add/',
'/api/users/edit/1',
'/api/users/',
'/api/account/view/1',
'/api/account/',
'/not/a/valid/path']
l = ['/api/users/*', '/api/account/*']
patterns = [re.compile(re.sub("\*$", ".*", s)) for s in l]
>>> [path for path in paths if any(p.match(path) for p in patterns)]
['/api/users/add/',
'/api/users/edit/1',
'/api/users/',
'/api/account/view/1',
'/api/account/']
如果您的通配符总是查询字符串中的最后一个内容,我建议将其切掉并使用。否则,请使用解释“glob”样式通配符的模块:
from fnmatch import fnmatch
def listglob(path, patterns):
return any(fnmatch(path, pat) for pat in patterns)
for path in paths:
print(path, listglob(path, l))
如果我理解正确,您想看看通配符模式是否正确。为此,您可以使用
glob
中的fnmatch
模块。假设你有这个:
l = [
'/api/users/*',
'/api/account/*'
]
paths = [
'/api/users/add/'
'/api/users/edit/1',
'/api/users/',
'/api/account/view/1',
'/api/account/',
'/non/existent/path'
]
你可以得到这个:
>>> import fnmatch
>>> [any(fnmatch.fnmatch(path, pat) for pat in l) for path in paths]
[True, True, True, True, False]
对于此问题,推荐使用已发布的
fnmatch
解决方案,但是,下面的答案说明了一种非导入解决方案:
def matchs_path(_pattern, _input):
_a, _b = filter(None, _pattern.split('/')), filter(None, _input.split('/'))
while True:
_val, _val2 = next(_a, None), next(_b, None)
if _val is None and _val2 is None:
return True
if _val != '*' and _val != _val2:
return False
if _val == "*":
_to_see = next(_a, None)
if _to_see is None:
return True
while True:
c = next(_b, None)
if c is None:
return True
if c == _to_see:
break
输出:
{
"/api/users/*": {
"/api/users/add/": true,
"/api/users/edit/1": true,
"/api/users/": true,
"/api/account/view/1": false,
"/api/account/": false,
"/going/to/fail/here": false,
"/new/additional/abc/test/here": false
},
"/api/account/*": {
"/api/users/add/": false,
"/api/users/edit/1": false,
"/api/users/": false,
"/api/account/view/1": true,
"/api/account/": true,
"/going/to/fail/here": false,
"/new/additional/abc/test/here": false
},
"/new/*/test/here": {
"/api/users/add/": false,
"/api/users/edit/1": false,
"/api/users/": false,
"/api/account/view/1": false,
"/api/account/": false,
"/going/to/fail/here": false,
"/new/additional/abc/test/here": true
}
}
请回答您的问题,并提供您为解决此问题而编写的代码。如果通配符始终位于路径的末尾,则不需要通配符匹配,只需使用前缀匹配即可。如果您确实需要通配符匹配,请使用适当的库(
fnmatch
)如果l
中的路径没有*
,即需要完全匹配,该怎么办?@tobias_k在这种情况下,第一次编辑会起作用,如果你从l
中删除*
,它将返回False-True-False-True
,但是如果你只是删除*
,你如何区分允许后缀的路径和不允许后缀的路径呢?啊,在这种情况下,我认为最好的方法就是前面描述的fnmatch
fnmatch
是它自己的模块,glob
只使用它。或者您可以使用fnmatch.translate
为您转换所有通配符。但是,既然Python也支持glob语法,为什么还要麻烦呢?问题的标题是“通配符列表匹配”。您的通配符支持在哪里?