I have a JS string that needs several of its chars replaced.
For example, for input string:
s = 'ABAC'
I would want to replace all B
s with C
s and vice versa. However, doing a standard regex replace is not good enough since the replace()
s should not occur in lockstep but rather in a single pass on the string.
>>> s.replace(/B/g, 'C').replace(/C/g, 'B')
'ABAB' // not good
Is there an elegant way to do multiple string replace()
in a single pass?
(Solution must work for any arbitrary char replacement)
I have a JS string that needs several of its chars replaced.
For example, for input string:
s = 'ABAC'
I would want to replace all B
s with C
s and vice versa. However, doing a standard regex replace is not good enough since the replace()
s should not occur in lockstep but rather in a single pass on the string.
>>> s.replace(/B/g, 'C').replace(/C/g, 'B')
'ABAB' // not good
Is there an elegant way to do multiple string replace()
in a single pass?
(Solution must work for any arbitrary char replacement)
Share Improve this question asked Mar 2, 2012 at 15:08 Yuval AdamYuval Adam 165k95 gold badges317 silver badges404 bronze badges3 Answers
Reset to default 9var str = 'ABACACCBA',
out = str.replace(/[CB]/g, function(c) {
return {
"B" : "C",
"C" : "B"
}[c];
});
console.log(out); /* ACABABBCA */
all you have to do is to define all characters to match and then an object with swapping rules. An alternative can be also done in this way
var str = 'ABACACCBA',
out = str.replace(/\w/g, function(c) {
return {
"B" : "C",
"C" : "B"
}[c] || c;
});
console.log(out); /* ACABABBCA */
in this example you execute the function for every character matched, but you make a swap only if you defined an entry into the object (otherwise you return the original character).
It's clearly more expensive (so better use the first example) but in this case you avoid to list all characters to match in the regular expression.
You want a translate
function; see this question for an example implementation.
There may well be neater ways to do it, but I usually do something simple like this....
s.replace(/B/g, '##_B_##').replace(/C/g, 'B').replace(/##_B_##/g, 'C');
Basically, make the Bs unique before replacing C with B so that the original Bs can still be identified.