RegExp在Function构造函数中匹配行为异常的原因及修正方案
这个问题的核心其实是模板字符串的转义处理加上错误的RegExp调用方式导致的,我来给你拆解清楚,再帮你修复:
问题根源
1. 模板字符串里的反斜杠被悄悄转义了
你在Function构造函数的模板字符串里写了正则字面量/\(([^)]+)\)/,但模板字符串中的\是转义字符——当模板字符串被解析时,\(会被直接转换成普通的(,\)会变成普通的)。也就是说,实际传递给Function的代码里,正则变成了/(([^)]+))/gi,而不是你原本想要的/\(([^)]+)\)/gi。
这就导致Function内部的正则在找两层括号里的内容,但你的输入字符串只有一层括号,自然匹配不到正确结果。
2. 错误的RegExp构造函数用法
你写的new RegExp(/\(([^)]+)\)/, "gi")其实是不符合ES6+规范的:当RegExp构造函数的第一个参数是正则对象时,第二个参数(flags)是不允许存在的,会直接抛出TypeError。虽然某些旧环境可能不报错,但它会忽略你传入的flags,导致正则的行为和预期不符。
修复方案
我们需要解决这两个问题,让Function内部的正则和直接调用行为完全一致:
方案一:正确转义模板字符串中的反斜杠
在模板字符串里,要表示正则中的反斜杠,必须写两个\\来转义,这样Function解析时才会得到正确的反斜杠。这里我们直接用正则字面量更简洁:
var message = "I expected two hundred and three fifty ($200) and ($350) dollars from this statement"; var extractResult = (a) => { const inputFn = new Function("val", ` const pattern = /\\(([^)]+)\\)/gi; const result = val.match(pattern); return result; `); return inputFn(a); } console.log("direct", message.match(/\(([^)]+)\)/gi)) console.log("function",extractResult(message))
方案二:用RegExp的字符串参数形式
如果你更习惯用new RegExp,可以直接传递字符串形式的正则,同样注意转义反斜杠:
var message = "I expected two hundred and three fifty ($200) and ($350) dollars from this statement"; var extractResult = (a) => { const inputFn = new Function("val", ` const pattern = new RegExp("\\(([^)]+)\\)", "gi"); const result = val.match(pattern); return result; `); return inputFn(a); } console.log("direct", message.match(/\(([^)]+)\)/gi)) console.log("function",extractResult(message))
额外提示:修正直接调用的写法
你原来的直接调用message.match(new RegExp(/\(([^)]+)\)/, "gi"))是错误的,建议直接用正则字面量message.match(/\(([^)]+)\)/gi),或者用new RegExp的字符串参数形式,避免出现语法错误。
最终效果
修复后,两次console.log都会输出["$200", "$350"],和你的预期完全一致。
内容的提问来源于stack exchange,提问作者Kamalakannan J

