【问题标题】:Javascript: what's the point of RegExp.compile()?Javascript:RegExp.compile() 的意义何在?
【发布时间】:2010-10-27 10:51:34
【问题描述】:

我有一种情况,我想从用户那里获取一个正则表达式,然后针对几千个输入字符串运行它。在手册中,我发现RegExp 对象有一个.compile() 方法,用于在这种情况下加快速度。但是,如果我已经在构造函数中传递了正则表达式字符串,为什么还要再次将它们传递给它呢?也许构造函数自己做compile()

【问题讨论】:

    标签: javascript regex compilation


    【解决方案1】:

    如果你使用/,你必须先编译你的正则表达式才能使用它,试试这个:

    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") )

    【讨论】:

    • 哇,这很有趣。我刚查了一下,你是对的!不过在 MDN 中没有提到。
    • 在使用RegExp 构造函数时不应使用正斜杠。正斜杠用于开始和结束RegExp literal,它们不是模式的一部分(除非您实际上是要匹配正斜杠)。 IMO,这实际上是 compile 中的错误行为,不应依赖。
    • 为了说明这一点 - new RegExp('/[a-zA-Z]/').test('/a/') true。正斜杠被正确解释为模式的一部分。 compile() 实际上改变了这个(Chrome 85),我认为它不应该。但是,compile() 本身现在在 MDN 中被标记为已弃用。
    【解决方案2】:

    RegExp().compile() method is deprecated。它与构造函数基本相同,我认为这就是它被弃用的原因。你现在应该只需要使用构造函数。

    换句话说,你曾经能够做到这一点:

    var regexp = new RegExp("pattern");
    regexp.compile("new pattern");
    

    但现在它与简单地调用没有什么不同:

    var regexp = new RegExp("pattern");
    regexp = new RegExp("new pattern");
    

    【讨论】:

      【解决方案3】:

      对于 Opera 11,运行 RegExp.compile() 实际上会导致错误。

      显然,当 Opera “编译”正则表达式时,它会将 re.source 字符串包装在正斜杠中(例如,re.source == "^(.)" 变为 "/^(.)/")。如果您手动编译正则表达式,Opera 不会识别这个事实并继续编译它(re.source 变为 "//^(.)//")。每次编译都会产生一组额外的正斜杠,这会改变正则表达式的含义并导致错误。

      【讨论】:

        【解决方案4】:

        据我所知,RegExp.compile 所做的只是替换 RegExp 对象的底层正则表达式。我认为 compile 在过去可能有价值,但所有现代 JS 引擎在第一次调用时“编译”正则表达式并缓存“编译”版本。

        【讨论】:

        • 哪些引擎会缓存正则表达式?他们总是这样做吗?表达式在缓存中保留多长时间?我对 V8 特别感兴趣。
        猜你喜欢
        • 2020-11-10
        • 2023-03-29
        • 2012-12-09
        • 2016-04-14
        • 2023-03-04
        • 2011-09-06
        • 2012-11-14
        • 2016-11-30
        • 2012-05-19
        相关资源
        最近更新 更多