I want to write a .replace
function in JavaScript that implements the even-odd rule of negative signs in algebra. In a series of negative and positive signs:
So I would then do .replace(/regex for case1/, "-")
and .replace(/regex for case2/, "+")
. Any idea on how to do this?
Here are example strings:
\frac{a^{n+-m}}{b}
-> \frac{a^{n-m}}{b}
abc+cde=ghj--+--hsnj
-> abc+cde=ghj+hsnj
Well you could replace all +
s with --
and then substitute accordingly:
expr.replace(/\+/g, '--').replace(/(--)+-/g, '-').replace(/--/g, '+')
Or you could use a function in your .replace
to count the number of -
s:
expr.replace(/[-+]+/g, function(signs){
return '+-'[signs.replace(/\+/g, '').length % 2];
});
As vks points out, regular expressions can't, strictly speaking, count. You can cancel out pairs as in Andris's answer, but as you can see the regexps get a bit long when you cover all the cases. An alternative is to combine regexp matching with a normal function:
function do_replacement(x) {
return x.replace(/[+-]+/g,
function (r) {
return r.replace(/\+/g, '').length % 2? '-' : '+';
}
);
}
This splits the task into two parts:
+
and -
+
s from the matched string, and count the remaining characters (which, thanks to the original regexp, can only be -
s)+
or a -
, based on whether the count is even (i.e., length % 2
is zero) or odd([^-+]|^)(?:[+]*-[+]*-)*[+]*-[+]*([^+-])
for odd number of hyphens, as seen https://regex101.com/r/fU0vY7/4 , needs to be replaced with $1-$2
([^-+]|^)(?:[+]*-[+]*-[+]*)+([^+-])
for even number of hyphens, as seen https://regex101.com/r/fU0vY7/5 , needs to be replaced with $1+$2
You can use both replaces on the same string. So far everything that I tested worked, including your examples. If something is off, do tell.
It would be more convenient to avoid capture groups, but the lack of lookbehind in javascript forced me to add the capture groups and $1+-$2
respectivelly
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With