首页 > 解决方案 > 通过 API 传递正则表达式会导致错误

问题描述

我在 NodeJS 中使用 Express 创建了一个 API,它使用 NeDB 作为其数据库。

我检查了文档,我可以看到有一种方法可以使用正则表达式过滤结果,以便在 SQL 中执行类似于“like”的操作。

在创建硬编码 JSON 对象以用作过滤器时,我能够使正则表达式工作,但是当通过我的 API 传递过滤器时,NeDB 报告以下错误:

Error: $regex operator called with non regular expression

我的测试数据库包含以下文件:

[
    {
        "test": "Hello",
        "other": "Goodbye",
        "_id": "9T0WaZ240q6ZK747"
    },
    {
        "test": "sup!",
        "other": "Ta ta",
        "extra": "something",
        "_id": "jLUzEZjLDVX1lmU5"
    }
]

当我find()使用硬编码的 JSON 过滤器对数据执行 a 时,它将返回正确的结果,例如

{
     test: {
         $regex: /hell/i
     }
}

将返回数据库中的第一条记录。

但是,当我find()从传递 JSON 对象过滤器的 API 调用该函数时,我收到前面提到的错误。

我的 API 中的过滤器添加如下:

{ test: { '$regex': '/hell/i' } }

看起来可能是单引号引起了一些问题,但即使将它们剥离后它也不起作用。我得到相同的错误或其他一些 JSON 解析错误。

我检查了 NeDB 的代码,并在model.js文件中添加了一行以将它检测到的正则表达式打印到控制台。在这两种情况下(有效的硬编码方法和 API 方法),正则表达式都返回为:

/hell/i

因此,NeDB 似乎为这两个调用接收到相同的表达式,但由于某种原因,API 方法会引发错误。

有没有人尝试使用该方法将 JSON 过滤器传递给 NeDB 实例find()并成功过滤?

我正在使用 Postman 进行 API 测试。

标签: javascriptregexexpressnedb

解决方案


我现在设法找到了一种解决方案。这绝不是完美的,仍然需要更多的工作和测试。

我最终修改了model.jsNeDB 中的文件,更具体地说是comparisonFunctions.$regex函数。我添加了一个额外的检查来查看传入的正则表达式是否可以从其字符串形式转换为正则表达式。该model.js文件现在如下所示:

comparisonFunctions.$regex = function (a, b) {

  if (!util.isRegExp(b)) {

    try {

      // convert the string based regex into an actual regular expression
      b = new RegExp(b.replace(/[\\/]/g, ""), 'i');

      // check again if it worked
      if (!util.isRegExp(b))
        throw new Error("$regex operator called with non regular expression");

    } catch {

      // we were not working with a regex
      throw new Error("$regex operator called with non regular expression");

    }
  }

  if (typeof a !== 'string') {
    return false
  } else {
    return b.test(a);
  }
};

所以现在如果我将它传递给我的 API:

{
    "test": {
        "$regex": "/ell/"
    }
}

它将返回test字段 ==的数据库中的第一个文档Hello

任何关于如何使这个更整洁和/或反馈的建议将不胜感激。


推荐阅读