Reputation: 21
I was presented with a JavaScript code challenge to create a function that will substitute all instances of a, e, i, o, u in a string with 0, 1, 2, 3, 4 (respectively). For example, "How about this string?" should become "H3w 0b34t th2s str2ng?"
Here's how I solved the problem:
const hackerSpeak = (str) => {
return str.replace(/[aA]/g, 0).replace(/[eE]/g, 1).replace(/[iI]/g, 2).replace(/[oO]/g, 3).replace(/[uU]/g, 4)
}
I'm fairly new to RegEx, and find myself wondering if there's a simpler way that would avoid chaining. Could I combine the RegEx into one expression that would know to replace aeiou with 01234 respectively?
An answer on this question led me to look into capture groups and back referencing, but it seems that's for re-ordering/swapping the aeiou characters rather than replacing them with 01234. (Though I'm happy to be corrected.)
Upvotes: 1
Views: 334
Reputation: 89294
You can use replace
with a callback.
const hackerSpeak = (str) => {
return str.replace(/[aeiou]/gi, x => 'aeiou'.indexOf(x.toLowerCase()));
}
Comment from Pointy:
To add some detail, the callback function is passed each match. The callback function returns what
.replace()
should use to replaced the matching part of the string. Here, thegi
suffix on the regex makes it a "global" match, so.replace()
will keep trying until the end of the source string, andi
makes it ignore case (so upper and lower case both match).
Upvotes: 5
Reputation: 19319
If you want to be able to vary the mapping from e.g. a -> 0
to something else then you can use this approach:
const str = "the cat sat on the mat and the cow in the undergrowth";
const mapping1 = { a: 0, e: 1, i: 2, o: 3, u: 4 }
const mapping2 = { a: "!", e: "foo", i: "bar", o: "fizz", u: "buzz" }
const hackerSpeak = (str, mapping) => {
return str.replace(/(a)|(e)|(i)|(o)|(u)/gi, k => mapping[k]);
}
console.log(str);
console.log(hackerSpeak(str, mapping1));
console.log(hackerSpeak(str, mapping2));
Upvotes: 0