匹配反应路由器路径声明的RegEx

时间:2020-02-06 15:07:28

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

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

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检索的位置,以匹配所有与反应路由器术语中的键相匹配的路径,例如:

  • (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')

以及所有反应路由器路径,因此这也应该起作用:

  • (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

1 个答案:

答案 0 :(得分:1)

根据您的评论,我对代码进行了一些调整,并为您的查找编写了说唱歌手功能。 创建网址时必须注意以下规则:

  • 最后一个id总是被{id}代替
  • 所有其他ID都被替换为不带复数且附加了“ Id”的URL部分(“ / 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