正则表达式与/ g修饰符和eval - 在FireFox和Chrome中的奇怪行为 [英] Regular Expression literal with /g modifier and eval - weird behaviour in FireFox and Chrome

查看:240
本文介绍了正则表达式与/ g修饰符和eval - 在FireFox和Chrome中的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一些javascript代码中遇到了一些奇怪的行为,但只在Firefox和Chrome中。 IE浏览器很好。



我已经隔离了这个问题,并创建了一个小页面,以便您自己查看行为。从本质上来说,就好像在 MethodC 中的正则表达式对象被重用于MethodC的方法调用一样,即使它是一个局部变量。有人可以解释这种行为吗?

 < html> 
< head>
< script type =text / javascript>
函数RunDemo()
{
var subject =01234 555 6789; (var i = 1; i <= 10; i ++){
MethodA(subject,i);


MethodB(subject,i);
MethodC(subject,i);



// OK,OK,OK,OK,OK,OK,OK,OK,OK
function MethodA(subject,iteration)
{
var myRegexp = new RegExp(5,g);
var matches = myRegexp.exec(subject);
AddItem(matches?OK:no match,listA);

$ b $ // OK,OK,OK,OK,OK,OK,OK,OK
函数MethodB(subject,iteration)
{
var myRegexp = / 5 /;
var matches = myRegexp.exec(subject);
AddItem(matches?OK:no match,listB);
}

// OK,OK,OK,不匹配,OK,OK,OK,不匹配,OK,OK(在FireFox和Chrome中,IE浏览器正常)
函数MethodC(主题,迭代){
var myRegexp = / 5 / g;
var matches = myRegexp.exec(subject);
AddItem(matches?OK:no match,listC);


函数AddItem(itemText,listID){
var li = document.createElement(li);
li.innerHTML = itemText;
document.getElementById(listID).appendChild(li);
}

< / script>
< / head>
< body onload =RunDemo()>
< h2>方法A< / h2>
< ul id =listA>< / ul>

< h2>方法B< / h2>
< ul id =listB>< / ul>

< h2>方法C< / h2>
< ul id =listC>< / ul>
< / body>
< / html>


解决方案

V8和spidermonkey中的优化器创建一个regex对象他们看到一个正则表达式并重用它。



根据ECMA3,这是符合规定的行为,但在ECMA5中将不符合规定。


7.8.5正则表达式文本正则表达式文本是一个输入元素,被转换为RegExp对象(section 15.10)当
被扫描时。该对象在包含程序或函数开始评估之前创建。对
文字的评估会产生对该对象的引用;它不会创建一个新的对象。
程序中的两个正则表达式字面值计算为从不比较为===的正则表达式对象,即使两个字符的
内容相同。 RegExp对象也可以在运行时由新的RegExp创建(第15.10.4节),或者作为一个函数调用
RegExp构造函数(见第15.10.3节)。



< ECMAScript语言规范第3版

比较:


7.8.5正则表达式字面量正则表达式字面量是一个输入元素,它是转换为RegExp对象(见15.10),每次计算
文字。一个程序中的两个正则表达式字面值计算正则表达式对象,即使两个字面值的内容相同,
也不会相互比较为===。 RegExp对象也可以在运行时由新的RegExp(见15.10.4)创建,或者作为函数调用RegExp构造函数(15.10.3)。

ECMAScript Language Specification Edition 5


以下是一些解决方法:


  • 不要对 exec 使用 / g 标志。

  • 从RegExp consructor而不是从正则表达式文字创建一个RegExp。


    或者说这两个都应该让问题消失。


    I was experiencing some weird behaviour in some of my javascript code, but only in Firefox and Chrome. IE is fine.

    I have isolated the problem and created a little page so you can see the behaviour yourself.

    Essentially, it appears as if the Regular Expression object in MethodC is being reused across method calls to MethodC, even though it's a local variable. Can someone explain this behaviour?

    <html>
    <head>
    <script type="text/javascript">
        function RunDemo()
        {
            var subject = "01234 555 6789";
    
            for (var i = 1; i <= 10; i++) {
                MethodA(subject, i);
                MethodB(subject, i);
                MethodC(subject, i);
            }
        }
    
        // OK, OK, OK, OK, OK, OK, OK, OK, OK, OK
        function MethodA(subject, iteration)
        {
            var myRegexp = new RegExp("5", "g");
            var matches = myRegexp.exec(subject);
            AddItem(matches ? "OK" : "no match", "listA");
        }
    
        // OK, OK, OK, OK, OK, OK, OK, OK, OK, OK
        function MethodB(subject, iteration)
        {
            var myRegexp = /5/;
            var matches = myRegexp.exec(subject);
            AddItem(matches ? "OK" : "no match", "listB");
        }
    
        // OK, OK, OK, no match, OK, OK, OK, no match, OK, OK (in FireFox and Chrome, IE is fine)
        function MethodC(subject, iteration) {
            var myRegexp = /5/g;
            var matches = myRegexp.exec(subject);
            AddItem(matches ? "OK" : "no match", "listC");
        }
    
        function AddItem(itemText, listID) {
            var li = document.createElement("li");
            li.innerHTML = itemText;
            document.getElementById(listID).appendChild(li);
        }   
    
    </script>
    </head>
    <body onload="RunDemo()">
        <h2>Method A</h2>    
        <ul id="listA"></ul>
    
        <h2>Method B</h2> 
        <ul id="listB"></ul>
    
        <h2>Method C</h2> 
        <ul id="listC"></ul>
    </body>
    </html>
    

    解决方案

    The optimizers in V8 and spidermonkey create a regex object when they see a regex literal and reuse it.

    Per ECMA3, this is compliant behavior, but it will become non-compliant in ECMA5.

    7.8.5 Regular Expression Literals

    A regular expression literal is an input element that is converted to a RegExp object (section 15.10) when it is scanned. The object is created before evaluation of the containing program or function begins. Evaluation of the literal produces a reference to that object; it does not create a new object. Two regular expression literals in a program evaluate to regular expression objects that never compare as === to each other even if the two literals' contents are identical. A RegExp object may also be created at runtime by new RegExp (section 15.10.4) or calling the RegExp constructor as a function (section 15.10.3).

    ECMAScript Language Specification Edition 3

    Compare to:

    7.8.5 Regular Expression Literals

    A regular expression literal is an input element that is converted to a RegExp object (see 15.10) each time the literal is evaluated. Two regular expression literals in a program evaluate to regular expression objects that never compare as === to each other even if the two literals' contents are identical. A RegExp object may also be created at runtime by new RegExp (see 15.10.4) or calling the RegExp constructor as a function (15.10.3).

    ECMAScript Language Specification Edition 5

    Here are some workarounds:

    • Don't use the /g flag with exec.
    • Create a RegExp from the RegExp consructor instead of from a regexp literal.

    Doing either or both of these should, I think, make the problem go away.

    这篇关于正则表达式与/ g修饰符和eval - 在FireFox和Chrome中的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆