如何将正则表达式作为对象映射键实现动静态路由匹配
解决方案
JS/TS 普通对象的键仅支持字符串、Symbol两种类型,即使TS声明
string | RegExp联合类型,运行时仍会自动将正则实例转为字符串作为键,根本无法实现动态路由匹配的需求。
实现思路
将静态路由和正则路由分开存储,兼顾性能与灵活度:
- 静态路由用Map存储,O(1)复杂度快速命中
- 正则路由单独存入数组,遍历匹配动态路由
完整代码实现
首先保留你原有节点类型定义即可,类内部实现如下:
// 静态路由映射:key为路由字符串,value为对应导航节点 private exactRouteMap = new Map<string, NavbarItemNode>(); // 正则路由规则列表 private regexRules: Array<{ matcher: RegExp; node: NavbarItemNode }> = []; // 新增路由节点方法 addRouteNode(matcher: string | RegExp, node: NavbarItemNode): void { if (typeof matcher === 'string') { this.exactRouteMap.set(matcher, node); return; } this.regexRules.push({ matcher, node }); } // 获取路由对应节点方法 getMatchedNode(routerLink: string): NavbarItemNode | undefined { // 优先匹配静态路由,性能最优 if (this.exactRouteMap.has(routerLink)) { return this.exactRouteMap.get(routerLink)!; } // 静态路由未命中,遍历正则规则匹配 for (const rule of this.regexRules) { if (rule.matcher.test(routerLink)) { return rule.node; } } return undefined; }
使用示例
// 添加静态路由 this.addRouteNode('/category/items', categoryNode); // 添加动态路由,注意正则用^$限定全匹配,避免误匹配其他路由 this.addRouteNode(/^\/items\/\d+$/, itemDetailNode); // 调用取值,替换原有直接取对象键的逻辑即可 // 匹配静态路由:传入'/category/items'直接返回对应节点 // 匹配动态路由:传入'/items/60'命中正则规则返回对应节点 return this.getMatchedNode(routerLink);
优化建议
- 正则规则较多时,可按业务优先级排序,高频匹配规则放数组前面,减少遍历次数
- 所有正则路由建议添加
^和$限定全路径匹配,避免出现部分匹配的异常情况
内容的提问来源于stack exchange,提问作者C0mpl3x
相关产品推荐
相关产品推荐

