通过 API 传递正则表达式会导致错误
Passing regex expression via API results in an error
我在 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"
}
]
当我使用硬编码 JSON 过滤器对数据执行 find()
时,它将 return 得到正确的结果,例如
{
test: {
$regex: /hell/i
}
}
将return数据库中的第一条记录。
但是,当我从我的 API 调用 find()
函数时,我正在传递 JSON 对象过滤器,我收到前面提到的错误。
我的 API 中的过滤器添加如下:
{ test: { '$regex': '/hell/i' } }
看起来可能是单引号导致了一些问题,但即使将它们剥离后也不起作用。我得到相同的错误或其他一些 JSON 解析错误。
我检查了 NeDB 的代码,并在 model.js
文件中添加了一行以向控制台打印它检测到的正则表达式。在这两种情况下(有效的硬编码方法和 API 方法)正则表达式被 returned 为:
/hell/i
因此,NeDB 似乎正在为两个调用接收相同的表达式,但由于某种原因,API 方法会引发错误。
有没有人尝试过使用 find()
方法将 JSON 过滤器传递给 NeDB 实例并成功过滤?
我正在使用 Postman 进行 API 测试。
我现在已经想出了一个解决方案。这绝不是完美的,仍然需要更多的工作和测试。
我最终修改了 NeDB 中的 model.js
文件,更具体地说是 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/"
}
}
它将return来自数据库的第一个文档,其中test
字段==Hello
任何有关如何使此 and/or 反馈更整洁的建议将不胜感激。
我在 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"
}
]
当我使用硬编码 JSON 过滤器对数据执行 find()
时,它将 return 得到正确的结果,例如
{
test: {
$regex: /hell/i
}
}
将return数据库中的第一条记录。
但是,当我从我的 API 调用 find()
函数时,我正在传递 JSON 对象过滤器,我收到前面提到的错误。
我的 API 中的过滤器添加如下:
{ test: { '$regex': '/hell/i' } }
看起来可能是单引号导致了一些问题,但即使将它们剥离后也不起作用。我得到相同的错误或其他一些 JSON 解析错误。
我检查了 NeDB 的代码,并在 model.js
文件中添加了一行以向控制台打印它检测到的正则表达式。在这两种情况下(有效的硬编码方法和 API 方法)正则表达式被 returned 为:
/hell/i
因此,NeDB 似乎正在为两个调用接收相同的表达式,但由于某种原因,API 方法会引发错误。
有没有人尝试过使用 find()
方法将 JSON 过滤器传递给 NeDB 实例并成功过滤?
我正在使用 Postman 进行 API 测试。
我现在已经想出了一个解决方案。这绝不是完美的,仍然需要更多的工作和测试。
我最终修改了 NeDB 中的 model.js
文件,更具体地说是 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/"
}
}
它将return来自数据库的第一个文档,其中test
字段==Hello
任何有关如何使此 and/or 反馈更整洁的建议将不胜感激。