2

First of all, pardon my hacky code, I'm just trying to try this out and I'm learning javascript for the first time. Basically, Given the string "abc!random{3}" would mean return a string that starts with "abc" and ends with a random number from 0-3.

Here is what I have:

var pattern=/!random{([^{]*?)}/gi;
var text="abc!random{3}def!random{4}ghi!random{!random{3}}";

while (pattern.test(text))
{
    text=text.replace(pattern, Math.random() * parseInt("$1")); 
}

The problem is the parseInt function. It seems like the $1 does not get passed to it..the value of it gets cleared or something. If I do:

text=text.replace(pattern, "$1");   

It correctly returns what is in between the { }, so the regex is working and the match is being stored in $1. However, as soon as I use it as a parameter to $1, it seems like the value of it is cleared. What gives?

ryeguy
  • 65,519
  • 58
  • 198
  • 260

2 Answers2

5

The second parameter to replace can either be a string to replace the entire match, within which, if present, all occurances of $1, $2, etc. are replaced with the captures OR it can be a function that takes two parameters (the match and the capture) and returns a replacement string for the capture:

var pattern=/!random{([^{]*?)}/gi;
var text="abc!random{3}def!random{4}ghi!random{!random{3}}";

text=text.replace(pattern,
    function(match,capture)
    {
        return Math.random() * parseInt(capture)
    });
WScript.echo(text);

Notice that the while loop is unnecessary: the regular expression already has the global flag set ("g"), which says to process the regex globally.

Also note that the function actually receives multiple (m) arguments: 1=the matched string, 2..m=the captures from left to right, m+2=the offset within the string where the match occured, and m+3=the entire string being matched. JavaScript allows the right-most arguments (of any function) to be omitted, which is why the example has only two.

James Hugard
  • 3,232
  • 1
  • 25
  • 36
  • Are you sure that the second parameter being a function is a standart implementation of JavaScript? If you can give a documentation link, that would be perfect since I have never came by a documentation likethis although it is a really cool feature =) – BYK May 23 '09 at 07:48
  • See section 15.5.4.11 of the Dec 1999 ECMAScript standard: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf. Here is a direct link to the MSDN page describing replace, which documents the same thing: http://msdn.microsoft.com/en-us/library/t0kbytzc(VS.85).aspx. – James Hugard May 23 '09 at 16:22
  • http://stackoverflow.com/questions/61088/hidden-features-of-javascript/65028#65028 helped me to understand why the function accepted multiple arguments in addition to James' answer. – Tate Johnson Oct 18 '09 at 12:23
0

The replace method is operating on the value that it's passed. That is, if it gets a string containing $0, $1, etc., then it replaces that with the correct match. However, what you wrote is first parsing the string "$1" as an integer, multiplying it by a random number, and then passing that as the replacement. So it's almost certainly passing it NaN (due to being unable to parse "$1"), which is not what you want.

So, instead of

text = text.replace(pattern, Math.random() * parseInt("$1"));

I would try

var matches = text.match(pattern);
text = text.replace(pattern, Math.random() * parseInt(matches[1]));
Rudd Zwolinski
  • 26,712
  • 17
  • 57
  • 60
  • That didn't work. matches[1] just returns the entire string, not the captured group (which is what's in between the { }) – ryeguy May 23 '09 at 04:02