我有一个字符串列表
DashboardComponent
路径就像
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
。
答案 0 :(得分:2)
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
编辑:
如果您想要一个将返回布尔值的方法:
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]))
输出:
False
False
False
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]))
输出:
False
False
True
False
True
答案 1 :(得分:2)
如果我理解正确,那么您想看看通配符模式是否成立。为此,您可以使用fnmatch
中的glob
模块。假设你有这个:
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]
答案 2 :(得分:1)
如果通配符始终是查询字符串中的最后一件事,则建议将其截断并使用.startswith()
。否则,请使用fnmatch
模块来解释“ 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))
答案 3 :(得分:1)
肯定已经建议针对此问题发布已经发布的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
patterns = ['/api/users/*', '/api/account/*', '/new/*/test/here']
data = ['/api/users/add/', '/api/users/edit/1', '/api/users/', '/api/account/view/1', '/api/account/', '/going/to/fail/here', '/new/additional/abc/test/here']
new_results = {i:{c:matchs_path(i, c) for c in data} for i in patterns}
输出:
{
"/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
}
}
答案 4 :(得分:0)
或列表理解:
print('\n'.join(['Path: {}, found in the list'.format(path) for path in paths if path in l]))
答案 5 :(得分:0)
您可以使用正则表达式将路径模式末尾的*
替换为.*
,然后将它们用作正则表达式本身以匹配列表中的路径。
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/']