JavaScript support for s///e.

    Date: 01/12/07 (Javascript Community)    Keywords: java

    I wrote the below (cut) function for those who mourn JavaScript's lack of an equivalent to Perl's s///e.

    function re_e(str, num_e)
    // Usage:
    // - Perl's $foo =~ s/bar/baz/e; is
    //   JavaScript's foo = foo.replace(/bar/, eval(re_e('baz')));
    // - The num_e argument specifies the number of 'e' flags (default 1). Note:
    //   foo = foo.replace(/bar/, eval(re_e('baz'), 0)); is equivalent to
    //   foo = foo.replace(/bar/, 'baz');, except that it's less efficient.
    // Rationale:
    // - In Perl, $1 and whatnot are interpolated into the right-hand-side
    //   *before* evaluation; in JavaScript, they're interpolated *after*.
    //   JavaScript offers an alternative system, where the right-hand-side is a
    //   a function instead of a string, but it is not always perfectly intuitive.
    //   This function maps Perl's /e approach to JavaScript's function approach.
    // Note that while the eval takes place in the caller's scope (thus allowing
    // local variables to be used, as in:
    //   var foo = 6; bar = bar.replace(/foo/g, eval(re_e('foo')));
    // which takes bar replaces all occurrences of "foo" with "6"), there is
    // internally another function going on, which means that function-local
    // variables (arguments and this and whatnot) are not accessible inside the
    // string: the internal other function's function-local variables are used
    // instead.
    {
     if(typeof(num_e) == 'undefined') num_e = 1;
     var evalstr = ''; for(var i = 0; i < num_e; ++i) evalstr += 'eval(';
     var rpstr = ''; for(var i = 0; i < num_e; ++i) rpstr += ')';
     return 'function () { return ' + evalstr + str.replace
     (
      /\$(?:\$|`|&|'|(\d)(\d?))|\$|[^$]+/g,
      function(str, p1, p2, offset, s)
      {
       if(str == '$' || str == '$$') return '"$" + ';
       if(str == '$`')
       {
        return 'arguments[arguments.length-1].substring(' +
               '0,arguments[arguments.length-2]) + ';
       }
       if(str == '$&') return 'arguments[0] + ';
       if(str == "$'")
       {
        return 'arguments[arguments.length-1].substring(' +
               'arguments[arguments.length-2]+arguments[0].length) + ';
       }
       if(str.match(/\$/)) // the numeric one
       {
        if(str == '$0' || str == '$00') return '"' + str + '" + ';
        if(p1 == '0' || p2 == '')
        {
         return '((arguments.length >= ' + p1 + p2 + ' + 3)?(arguments[' +
                p1 + p2 + ']):("' + str + '")) + ';
        }
        return '((arguments.length >= ' + p1 + p2 + ' + 3)?(arguments[' +
               p1 + p2 + ']):((arguments.length >= ' + p1 + ' + 3)?(arguments[' +
               p1 + '] + "' + p2 + '"):("' + str + '"))) + ';
       }
       return '"' + str.replace(/"/g, '\\"') + '" + ';
      }
     ) + '""' + rpstr + '; }';
    };

    So, I have a few questions:

    • Was this a good idea? Am I inappropriately trying to mold JavaScript in Perl's image? (I'm rather new to the Tao of JavaScript, as it were.)
    • Is this the right way to do it? I originally created a replaceEval function that operated like String.replace except for applying eval() a specified number of times (default 1), but I ended up scrapping that because the eval()s would get invoked in the scope of replaceEval's definition rather than in the scope of its invocation, preventing replacement-strings from using local variables (including local functions). I'm not sure if this is really the Right Way, though.
    • How inefficient is this? Obviously it involves applying a bunch of eval()s and String.replace()s, but I don't know exactly how intensive those are. Is this something to be concerned about? Is there a way to improve it?
    • Any other comments?

    (BTW, if the above function looks useful to you, feel free to use it.)

    Source: http://community.livejournal.com/javascript/124270.html

« cocktail builder: fully ajaxed || "dynamic" resizing »


antivirus | apache | asp | blogging | browser | bugtracking | cms | crm | css | database | ebay | ecommerce | google | hosting | html | java | jsp | linux | microsoft | mysql | offshore | offshoring | oscommerce | php | postgresql | programming | rss | security | seo | shopping | software | spam | spyware | sql | technology | templates | tracker | virus | web | xml | yahoo | home