【发布时间】:2010-10-27 10:51:34
【问题描述】:
我有一种情况,我想从用户那里获取一个正则表达式,然后针对几千个输入字符串运行它。在手册中,我发现RegExp 对象有一个.compile() 方法,用于在这种情况下加快速度。但是,如果我已经在构造函数中传递了正则表达式字符串,为什么还要再次将它们传递给它呢?也许构造函数自己做compile()?
【问题讨论】:
标签: javascript regex compilation
我有一种情况,我想从用户那里获取一个正则表达式,然后针对几千个输入字符串运行它。在手册中,我发现RegExp 对象有一个.compile() 方法,用于在这种情况下加快速度。但是,如果我已经在构造函数中传递了正则表达式字符串,为什么还要再次将它们传递给它呢?也许构造函数自己做compile()?
【问题讨论】:
标签: javascript regex compilation
如果你使用/,你必须先编译你的正则表达式才能使用它,试试这个:
var regex=new RegExp('/[a-zA-Z]/')
console.log("not compiled with escape /", regex.test("ciao") )
regex.compile()
console.log("compiled", regex.test("ciao") )
var regex=new RegExp('[a-zA-Z]')
console.log("not compiled, but no escape /", regex.test("ciao") )
【讨论】:
RegExp 构造函数时不应使用正斜杠。正斜杠用于开始和结束RegExp literal,它们不是模式的一部分(除非您实际上是要匹配正斜杠)。 IMO,这实际上是 compile 中的错误行为,不应依赖。
new RegExp('/[a-zA-Z]/').test('/a/') 是 true。正斜杠被正确解释为模式的一部分。 compile() 实际上改变了这个(Chrome 85),我认为它不应该。但是,compile() 本身现在在 MDN 中被标记为已弃用。
RegExp().compile() method is deprecated。它与构造函数基本相同,我认为这就是它被弃用的原因。你现在应该只需要使用构造函数。
换句话说,你曾经能够做到这一点:
var regexp = new RegExp("pattern");
regexp.compile("new pattern");
但现在它与简单地调用没有什么不同:
var regexp = new RegExp("pattern");
regexp = new RegExp("new pattern");
【讨论】:
对于 Opera 11,运行 RegExp.compile() 实际上会导致错误。
显然,当 Opera “编译”正则表达式时,它会将 re.source 字符串包装在正斜杠中(例如,re.source == "^(.)" 变为 "/^(.)/")。如果您手动编译正则表达式,Opera 不会识别这个事实并继续编译它(re.source 变为 "//^(.)//")。每次编译都会产生一组额外的正斜杠,这会改变正则表达式的含义并导致错误。
【讨论】:
据我所知,RegExp.compile 所做的只是替换 RegExp 对象的底层正则表达式。我认为 compile 在过去可能有价值,但所有现代 JS 引擎在第一次调用时“编译”正则表达式并缓存“编译”版本。
【讨论】: