注:标题上囊括了Node.js和javascript,但这里仅以Node.js作为讨论,因为两者的语法是一致的,只是使用的地方不一样!
RegExp是Node.js的原生对象,会有什么风险呢?
下面我们做一个简单的示例:
let str = "\\";
let regx = new RegExp(str);
结果输出如下:
SyntaxError: Invalid regular expression: /\/: \ at end of pattern
设想一种情况,当我们在Node.js里面,使用mongoose对mongodb按用户输入关键字来进行模糊查询时,一般情况下,都会使用RegExp来创建正则表达式对象。那么当用户输入了
\\
(两个反斜杠),我们后台的程序就抛出异常了,如果错误数量巨大 ,那么就可能发生程序挂掉,这是后端开发需要避免的风险。
如何防范?
在讨论如何防范之前,我们得弄明白,出错的原因在哪里,向下看:
- 在Node.js中,字符串中的
\
(反斜杠)代表转义标记,是对其后的一个或多个字符进行转义操作,解决字符串的嵌套及特殊字符间的表达冲突问题。而在字符串中\\
(两个反斜杠)仅表示一个字符\
(反斜杠),而在正则表达里面,\
也代表转义。 - 在Node.js中, RegExp的作用是以传入的字符串参数创建一个正则表达式对象,而其内部并没有对
\
进行转义,于是,本来我们期望的正则/\\/
在这里却变成了/\/
,这是不符合语法规范的,所以这就是为什么会报上面的SyntaxError
的原因了。
好了,知道出错原因,我们开始做防范措施了,以下是我的一个解决方案,可以根据需要自行制订:
let str = "\\";
str = str.replace(/\\/ig, "\\\\");
let regx = new RegExp(str);
等等,为什么要替换成功\\\\
(四个反斜杠),而不是两个反斜杠?以下解释一下(这里有点绕):
let str = "\\";
表示要匹配的是一个\
(一个反斜杠)字符;
str.replace
表示替换把一个反斜杠替换成两个反斜杠, 所以此时str
的值为\\\\
;
经过以上的操作,结果regx的值为/\\/
;
如果替换成两个反斜杠,最终也会报SyntaxError
的错误。