给定多个路径模板,如何将它们合并为一个完整的模板

问题描述

不确定标题是否具有描述性,但这是我的问题。给定路径和可选参数,例如:

/client/get
/admin/client/get
/admin/client/get/2

我如何生成一个表达该URL每种可能版本的模板。对于该示例,它将类似于:

/{admin}/client/get/{id}

我的主要问题是保持路径顺序。虽然我可以生成包含所有参数的路径,但似乎无法以正确的顺序进行操作。得到的模板如下:

/client/get/{id}/{admin}

我在python列表中将所有路径都作为字符串,没有特定的顺序,例如:

/client/get
/admin/client/get/<int:id>
/admin/client/get

解决方法

可能不是最优化的方法,但是我最终将路径段上的权重关联在一起。从最短的url开始,我检测到新的部分和被删除的部分,然后假定它们是参数。在最短路径上,我使用10的增量来保留我认为是合理的空间。 diff方法仅返回两个列表之间的差。我还在元组中使用了第三个元素,指示该参数是否可选,允许我添加一个“?”在模板中。该代码不是很干净,但是效果很好:

shortest_string = reduce(lambda a,b: a if len(a) <= len(b) else b,paths)
paths.remove(shortest_string)

shortest = [e for e in shortest_string.split('/') if len(e) > 0]
weighted = [((i + 1) * 10,v,False) for i,v in enumerate(shortest)]

for p in paths:
    psplit = [e for e in p.split('/') if len(e) > 0]
    new_elements = diff(psplit,shortest)
    removed_elements = diff(shortest,psplit)

    for w in weighted:
        if w[1] in removed_elements:
            w[2] = True
        if w[1] in psplit:
            i = psplit.index(w[1])
            psplit[i] = w
    for i,ps in enumerate(psplit):
        if i < len(psplit) - 2 and isinstance(psplit[i + 1],tuple) and not isinstance(ps,tuple):
            psplit[i] = (psplit[i + 1][0] - 1,ps,ps in new_elements)
            weighted.append(psplit[i])
        elif not isinstance(ps,tuple):
            psplit[i] = (psplit[i - 1][0] + 1,ps in new_elements)
            weighted.append(psplit[i])

template = '/'.join(['{' + (e[1][1:-1].split(':')[1] if e[1].startswith('<') else e[1]) + ('?' if e[2] else '') + '}'
                 if e[2] or e[1].startswith('<') else e[1] for e in sorted(weighted,key=lambda x: x[0])[1:]])
,

如果所有路径都在python列表中,则从选择最短路径开始,因为最短路径是缺少所有可选参数的路径(在示例中为“ / client / get”)

然后,您使用诸如RegExp之类的模式匹配在列表的开头或末尾浏览可选参数添加项

import re

# holds smallest possible url
shortest = '/client/get'

# holds the url template you want
template = '/client/get'

# iterates through URLs
for poss_url in url_list:

     # Checks beginning of URL
     match = re.search('w+' + shortest,poss_url)
     if match is not None:
          string = match.group()
          string = string[1:]
          string = string[:-len(shortest)]
          template = '/{' + string + '}' + template

     # Checks end of URL
     match = re.search(shortest + 'w+',poss_url)
     if match is not None:
          string = match.group()
          string = string[1:]
          string = string[:-len(shortest)]
          template = template + '{' + string + '}'

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...