【问题标题】:RegEx that match react router path declaration匹配反应路由器路径声明的正则表达式
【发布时间】:2020-05-22 16:18:25
【问题描述】:

我有一张以反应路由器路径为键的路线图,例如:

const routes = [
  {
    page: "mySettings",
    label: "pages.mySettings",
    path: "/professionels/mes-reglages.html",
    exact: true
  },
  {
    page: "viewUser",
    label: "pages.viewUser",
    path: "/users/:id/view.html",
    exact: true
  }
];

我想从使用useHistory().location.pathname 检索的位置匹配所有与 react-router 术语中的键匹配的路径,例如:

  • (pathname) => get(routesMap, "/professionels/mes-reglages.html") => 应该匹配 routesMap.get('/professionels/mes-reglages.html')
  • (pathname) => get(routesMap, "/users/11/view.html") => 应该匹配 routesMap.get('/users/:id/view.html')

以及所有 react-router 路径,所以这也应该有效:

  • (pathname) => get(routesMap, "/users/11/settings/10/items/24/view.html") => 应该匹配 routesMap.get('/users/:userId/settings/:settingId/items/:id/view.html')

我从这里开始,知道如何使用正则表达式来做到这一点吗?

https://codesandbox.io/s/youthful-wing-fjgm1

【问题讨论】:

    标签: javascript node.js reactjs react-router react-router-dom


    【解决方案1】:

    根据您的 cmets,我稍微调整了代码并为您的查找编写了一个 rapper 函数。 创建 url 时必须注意以下规则:

    • 最后一个 id 总是被 {id} 替换
    • 所有其他 id 都被 url 部分替换为不带复数和附加“Id”的 id (“/users/111” -> “/users/{userId}”)

    这将是函数:

    const getRouteFromPath = (map, url) => {
      if (url.match(/\/\d+\//g).length > 1) {
        let allowedUrlPart = getAllowedIdQualifier(map);
        let urlParts = url.match(/(?<=\/)\w+(?=\/\d+\/)/g);
        urlParts.forEach(val => {
          if (!allowedUrlPart.includes(val)) {
            urlParts = urlParts.slice(urlParts.indexOf(val), 1);
          }
        });
        urlParts.forEach((val, key, arr) => {
          if (key === arr.length - 1) {
            let regex = new RegExp("(?<=/" + val + "/)\\d+", "g");
            let replacement = ":id";
            url = url.replace(regex, replacement);
          } else {
            let regex = new RegExp("(?<=/" + val + "/)\\d+", "g");
            let replacement = ":" + val.slice(0, -1) + "Id";
            url = url.replace(regex, replacement);
          }
        });
        return map.get(url);
      } else {
        url = url.replace(/\/\d+\//g, "/:id/");
        return map.get(url);
      }
    };
    
    const getAllowedIdQualifier = map => {
      let allowedQualifiers = [];
      map.forEach(val => {
        let allowed = val.path.match(/(?<=\/)\w+(?=\/:)/g);
        allowed.forEach(e => {
          if (!allowedQualifiers.includes(e)) {
            allowedQualifiers.push(e);
          }
        });
      });
      return allowedQualifiers;
    };
    
    export default getRouteFromPath;
    
    

    作为参数,您传入 url 以匹配作为第一个参数,将路线图作为第二个参数并调用函数 getRoute() 而不是直接 map.get() 调用您之前使用的位置。

    这里是调整 url 以遵循规则的示例,因为您需要一些规则才能应用 RegEx。

    编辑:

    我调整了脚本,使其首先读取地图并确定接受 id 的允许路径,然后根据实际 url 检查可能的 id。

    https://codesandbox.io/s/kind-moon-9oyj9?fontsize=14&hidenavigation=1&theme=dark

    【讨论】:

    • 那个 coule 在 manu 工作,但一般最后一个只是 {id}miles /users/10 => /users/{id}
    • 如何包装初始地图对象以保留地图属性但允许更多路径(例如计算的 url)用于获取地图?
    • 另外,你替换为你声明所有实体的方式。如果您可以通过检测已注册的占位符并计算此解决方案来自动完成它会更好
    • @DimitriKopriwa 根据您的 cmets 调整了我的答案
    • 我创建了一个带有修复 :id => codesandbox.io/s/exciting-cori-ufnpv 的代码框,它似乎工作正常,但它不是数字的防弹,我期待获得允许的版本。再次非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-09-30
    • 2019-01-28
    • 2011-11-05
    • 1970-01-01
    • 2022-10-19
    • 1970-01-01
    • 2022-08-11
    相关资源
    最近更新 更多