Jest中expect.stringMatching()正则表达式无效的语法错误问题
问题说明
我们有一个返回随机值的函数(本文中为crypto -> aes),需求是比较对象内的当前字符串与历史值不相等(因对象结构复杂,直接比较对象内的该字符串)。
但使用以下代码时出现报错:
const oldCiper = "oldRandom+String-/FromAny==Characters"; // 注意:原字符串中的\需要转义为\\,否则JS会解析为无效转义字符 const newCiper = "+newRandomString-\\From/Any==Charac+ters"; // 此处报错:SyntaxError: Invalid regular expression... expect({cipher: oldCiper }).toEqual({cipher: expect.not.stringMatching(newCiper)})
完整错误信息:
SyntaxError: Invalid regular expression: /+newRandomString-\From/Any==Charac+ters/: 无重复内容可匹配
问题原因
expect.not.stringMatching()会把传入的字符串直接当作正则表达式解析,但newCiper里包含+、/、\等正则特殊元字符:
+在正则中表示“匹配前面内容一次或多次”,放在开头会导致语法错误/是正则的分隔符,未转义会直接终止正则表达式\在正则中是转义符,未正确转义会导致后续字符解析异常
这些字符直接作为正则使用时,违反了正则语法规则,从而抛出错误。
解决方案
方案1:直接比较字符串(推荐)
如果需求是完全不等于目标字符串,不需要用正则匹配,直接用expect.not.toBe()配合expect.objectContaining()即可:
const oldCiper = "oldRandom+String-/FromAny==Characters"; const newCiper = "+newRandomString-\\From/Any==Charac+ters"; expect({cipher: oldCiper }).toEqual(expect.objectContaining({ cipher: expect.not.toBe(newCiper) }));
方案2:转义正则特殊字符
如果确实需要用正则匹配(比如模糊匹配场景),需要先将字符串中的正则特殊字符转义:
方式A:使用Node.js内置转义方法
const { RegExp } = require('node:util'); const oldCiper = "oldRandom+String-/FromAny==Characters"; const newCiper = "+newRandomString-\\From/Any==Charac+ters"; const escapedStr = RegExp.escape(newCiper); // 用^和$确保完全匹配整个字符串 expect({cipher: oldCiper }).toEqual({ cipher: expect.not.stringMatching(new RegExp(`^${escapedStr}$`)) });
方式B:手动实现转义函数
如果环境不支持内置转义,可以自己写转义函数:
function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } const oldCiper = "oldRandom+String-/FromAny==Characters"; const newCiper = "+newRandomString-\\From/Any==Charac+ters"; const escapedStr = escapeRegExp(newCiper); expect({cipher: oldCiper }).toEqual({ cipher: expect.not.stringMatching(new RegExp(`^${escapedStr}$`)) });
内容的提问来源于stack exchange,提问作者Илья Хоришко
相关产品推荐
相关产品推荐

