Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex to implement even-odd rule of negative signs

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:

  • Case 1: If there's an odd number of negative signs, it's equivalent to a negative sign
  • Case 2: If there's an even number of negative signs, it's equivalent to a positive sign.

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
like image 800
guillefix Avatar asked Aug 03 '15 11:08

guillefix


3 Answers

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];
});
like image 182
1983 Avatar answered Oct 30 '22 22:10

1983


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:

  1. Use a regexp to match any sequence of + and -
  2. In the replacement function, remove the +s from the matched string, and count the remaining characters (which, thanks to the original regexp, can only be -s)
  3. Return either a + or a -, based on whether the count is even (i.e., length % 2 is zero) or odd
like image 24
Rob Hague Avatar answered Oct 30 '22 21:10

Rob Hague


([^-+]|^)(?:[+]*-[+]*-)*[+]*-[+]*([^+-]) 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

like image 27
Andris Leduskrasts Avatar answered Oct 30 '22 22:10

Andris Leduskrasts