检查数组中是否存在带有参数的网址

时间:2020-01-08 08:35:54

标签: javascript regex url compare

我有一个数组,其中包含大量使用的网址,例如:

["PATCH /users/{userId}",
"PATCH /users/types/{userIdId}",
"PATCH /products/brands/{brandId}/image",
"PATCH /product-types/{productId}"];

我使用Mongodb作为数据库,并且id与userId = "5dce7b7e47224c477734e35d"类似。这是我的函数中的代码:

var havePerm = false;
var myUrl = "PATCH /users/5dce7b7e47224c477734e35d"
for (var i = 0; i < urls.length; i++) {
   // It compares if: "PATCH /users/5dce7b7e47224c477734e35d" equals "PATCH /users/{userId}"
   if (myUrl === urls[i]) { 
      havePerm = true;
   }
}
return havePerm;

在这种情况下,它应该返回true,但是返回false。

如果url没有参数(例如:{id}),则比较是直接的,但是对于PATCH,问题是我不知道如何在括号{}之间比较参数。

如何比较这些情况?用正则表达式?但我不知道该如何构建。

1 个答案:

答案 0 :(得分:0)

您可以分解字符串(方法和路径组件),然后比较各个部分,这是一个示例:

const urls = ["PATCH /users/{userId}",
  "PATCH /users/types/{userIdId}",
  "PATCH /products/brands/{brandId}/image",
  "PATCH /product-types/{productId}"
];

const myUrl = "PATCH /users/5dce7b7e47224c477734e35d";

function parse(str) {
  return str.split(/\s?\//);
}

function isPlaceholder(str) {
  return /\{[^}]+\}/.test(str);
}

function hasPermission() {
  const myUrlParsed = parse(myUrl);
  // check if any of the "urls" elements matches "myUrl"
  return urls.some(url => {
    const parsedUrl = parse(url);
    if (myUrlParsed.length === parsedUrl.length) {
      // check if all the "myUrlParsed" elements match all "parsedUrl" elements at the coresponding index or if the "parsedUrl" element is a placeholder
      return myUrlParsed.every((v, i) => v === parsedUrl[i] || isPlaceholder(parsedUrl[i]));
    }
    return false;
  });
}

console.log("has permission:", hasPermission());

这是将每个url分解为如下所示的数组:

["PATCH", "users", "{userId}"]

,然后再次检查每种类型的数组,再检查从myUrl字符串生成的数组。

检查将检查对应索引处的每个数组元素是否相等或该元素是否是占位符(以{开始,以}结尾)。

执行此操作的另一种方法是将url转换为正则表达式,下面是一个示例:

let urls = ["PATCH /users/{userId}",
  "PATCH /users/types/{userIdId}",
  "PATCH /products/brands/{brandId}/image",
  "PATCH /product-types/{productId}"
];
const myUrl = "PATCH /users/5dce7b7e47224c477734e35d";

function escapeRegex(s) {
  return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};

urls = urls.map(url => {
  const regExpStr = url.split(/\{[^\}]+\}/)
    .map(escapeRegex)
    .join('[^\/]+');
  return new RegExp(regExpStr);
});

function hasPermission() {
  return urls.some(url => url.test(myUrl));
}

console.log("Has permission:", hasPermission());