I've spotted a very strange issue in IE7|8 when using special replacement patterns:
'moo$$e'.replace( /\$/g, '$$$$' );
'moo$$e'.replace( '\$', '$$$$', 'g' );
Latest Chrome:
moo$$$$e moo$$$e
Latest Firefox:
moo$$$$e moo$$$$e
IE7|8:
moo$$$$e moo$$$$$e
I know that flags parameter is nothing like a standard, hence the difference between Firefox and Chrome in the second case. I'm cool with it.
However, what I see in IE7|8 is really odd (still second case). I tried playing with '\x24'
, escaping and stuff but I cannot find any way to have this working as expected ($$
stands for $
).
I know that this could be easily done with split()
and join()
like:
'moo$$e'.split( '$' ).join( '$$' );
> "moo$$$$e"
but I'm really, really curious what's wrong with IE. Is there any explanation?
See the live example.
Test case
I revisited the test case with results to present it as follows:
var results = [
'YY'.replace( /Y/g, '$$' ),
'YY'.replace( 'Y', '$$', 'g' ),
'YY'.replace( 'Y', function( a, b ) { return '$$'; }, 'g' ),
'YY'.replace( /Y/g, function( a, b ) { return '$$'; })
];
console.log( results.join( '\n' ) );
Results
Chrome
$$ // '$$' -> '$', global flag used, every 'Y' -> '$'
$Y // '$$' -> '$', global flag ignored, first 'Y' -> '$'
$$Y // '$$' -> '$$', global flag ignored, first 'Y' -> '$$'
$$$$ // '$$' -> '$$', global flag used, every 'Y' -> '$$'
Firefox
$$ // '$$' -> '$', global flag used, every 'Y' -> '$'
$$ // '$$' -> '$', global flag used, every 'Y' -> '$'
$$$$ // '$$' -> '$$', global flag used, every 'Y' -> '$$'
$$$$ // '$$' -> '$$', global flag used, every 'Y' -> '$$'
IE7 and 8
$$ // '$$' -> '$', global flag used, every 'Y' -> '$'
$$Y // '$$' -> '$$', global flag ignored, first 'Y' -> '$$'
$$Y // '$$' -> '$$', global flag ignored, first 'Y' -> '$$'
$$$$ // '$$' -> '$$', global flag used, every 'Y' -> '$$'
Conclusions
Chrome ignores 'g'
flag as a third parameter of String.replace
since flags used this way don't belong to any standard.
IE assumes $$
to be string rather that replacement control and ignores global flag in this case:
'YY'.replace( 'Y', '$$', 'g' );
The simplest solution make sure that results are always the same is to use a RegExp
object with flags (/foo/flags
) as a first parameter and either string or function as a second parameter.
If string is a second parameter, $$
converts to $
. If this is a function-driven replacement, there's no such conversion.