One option is to use replace
, passing as the second parameter a function of callback:
const operators = {
plus: '+',
minus: '-',
multiplied: '*',
divided: '/'
};
let question = 'What is 4 plus 6? And 4 minus 6, 4 multiplied 6, 4 divided 6';
let s = question.replace(/\b(plus|minus|multiplied|divided)\b/g, function(match, op) {
return operators[op];
});
console.log(s) // What is 4 + 6? And 4 - 6, 4 * 6, 4 / 6
I use the shortcut \b
(word Boundary, if you want a more detailed explanation about it, see here) to specify that before and after the text there is no alphanumeric character (so I only take the words "plus", "Minus", etc, when they are "isolated" from the text - if you have something like "Multiplus", the regex ignores).
The words are in parentheses to form a catch group (and also because of the order of precedence, see here and here how does it matter).
Then I pass a function of callback received as parameters the match
and the first capture group (which I called op
). Then, just return the symbol corresponding to the text that was captured, which is in the first group (in the variable op
). The result of the function is what will be used in the substitution, i.e., it exchanges "plus" for "+", "Minus" for "-" and so on.
Remember that the rest of the text (the "What is" and the commas I put in the example) is not removed.
If you want words to be replaced only if you have numbers before and after, you can switch to:
const operators = {
plus: '+',
minus: '-',
multiplied: '*',
divided: '/'
};
let question = 'What is 4 plus 6? And 4 minus 6, 4 multiplied 6, 4 divided 6, plus without numbers.';
let s = question.replace(/(\d+)\s*\b(plus|minus|multiplied|divided)\b\s*(\d+)/g, function(match, n1, op, n2) {
return `${n1}${operators[op]}${n2}`;
});
console.log(s) // What is 4+6? And 4-6, 4*6, 4/6, plus without numbers.
Now I have included 2 more capture groups with \d+
(one or more digits) and with optional spaces (\s*
- zero or more spaces), then the function of callback should receive further arguments to match these additional groups (n1
is the number before the operation, op
is the text and n2
is the number after the operation).
On the return of the function I change the text for the symbol of the operation and keep the numbers. I didn’t put space between them, but if you want a space, just do return `${n1} ${operators[op]} ${n2}`;
.