eslint-plugin-unicorn icon indicating copy to clipboard operation
eslint-plugin-unicorn copied to clipboard

Enforce `.replaceAll()` over `.split().join()` in `prefer-string-replace-all` rule

Open fisker opened this issue 4 years ago • 4 comments

Fail

foo.split('a').join('b');

Pass

foo.replaceAll('a', 'b');
// Not sure about this, maybe add `g` flag, result the same?
foo.split(/a+/).join('b');
// Different with foo.replaceAll('', 'b');
foo.split('').join('b');

fisker avatar Jul 23 '21 11:07 fisker

This is accepted.

sindresorhus avatar Jul 30 '21 14:07 sindresorhus

// Not sure about this, maybe add `g` flag, result the same?
foo.split(/a+/).join('b');

It's important to remember that calling split with a regular expression has some gotchas, such as if the regex has a capturing group:

'a_b_c'.split(/_/);
//=> [ 'a', 'b', 'c' ]
'a_b_c'.split(/(_)/);
//=> [ 'a', '_', 'b', '_', 'c' ]

papb avatar Aug 15 '21 23:08 papb

The second argument also little different https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement

'1_2_3'.split('_').join('$&')
//=> '1$&2$&3'
'1_2_3'.replaceAll('_', '$&')
//=> '1_2_3'
'1_2_3'.split('_').join('$$')
//=> '1$$2$$3'
'1_2_3'.replaceAll('_', '$$')
//=> '1$2$3'

fisker avatar Nov 07 '22 06:11 fisker

The fix can double each $ to $$ in the replacement argument if it’s known to be a string literal (e.g. .split('_').join('$$').replaceAll('_', '$$$$')), and otherwise use a function (e.g. .split('_').join(s).replaceAll('_', () => s)).

andersk avatar Apr 05 '24 00:04 andersk