Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的通配符列表匹配_Python - Fatal编程技术网

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语法,为什么还要麻烦呢?问题的标题是“通配符列表匹配”。您的通配符支持在哪里?