javascript – Regex Doubt

Question:

Good night.

I need a regular expression that can capture the numbers/expressions before and after a certain character, like this ^ .

For example, in the string below I need it to return me (5 * 77 + 4)^6 and 7^3 :

5! + 8 - 5(ln(3)) + (5 * 77 + 4)^6 - 7^3

The expressions I created so far were these:

  • /((\()?(.)+(\))?)+(\^)+((\()?(.)+(\))?)/g

  • /\(*\w+\)*(\^)+\(*\w+\)*/g

It is important that he check that there is only one ^ .

In this example there is a functional application of the second case in a string, however I am not able to apply this in javascript.

Answer:

Well, what I wanted with capturing these numbers/expressions was to simulate the action of the exponential function with the ^ sign.

I got a way to do this, but it wasn't just regex .

First, I had to capture everything before the ^ so that it syntactically fits into the exponential function. For example:

In the string below, I would capture the (2 - 9) , ignoring the whitespace, regardless of their amount:

log(10) + (2 - 9) ^ 5

And then I would have to do the same with what was after the ^ , which in the example above would be the 5 .

After that I should apply these captures in the javascript Math, pow() function Math, pow() that performs the exponentiation, according to what has already been said, it would be:

Math.pow((2 - 9), 5)

And finally, I should repeat this capture>capture>concatenation process until there is no more ^ left in the middle of the string . So I could have an exponentiation within another exponentiation:

(2 ^ 3)^7

the Javascript

To capture what was before the ^ , the code was this:

function captureBefore(string) {
  var result;
  var n = string.indexOf("^");
  var i = n - 1;
  while (!(string.charAt(i) != " ")) {
    --i;
  }
  if (!(/\d/.test(string.charAt(i)))) {
    var nOpen = 1;
    var nClose = 0;
    while (nOpen != nClose) {
      if (string.charAt(i - 1) == ")") {
        ++nOpen;
      } else if (string.charAt(i - 1) == "(") {
        ++nClose;
      }
      i -= 1;
    }
    if (/[a-z]/.test(string.charAt(i - 1))) {
      while ((/[a-zA-Z.]/.test(string.charAt(i - 1)))) {
        i -= 1;
      }
    }
    result = string.substring(i, n);
  } else {
    while (/\d/.test(string.charAt(i)) || /[-|+|.]/.test(string.charAt(i))) {
      i -= 1;
    }
    result = string.substring(i + 1, n);
  }
  return result;
}

And for what was after:

function captureAfter(string) {
  var result;
  var n = string.indexOf("^");
  var i = n + 1;
  while (string.charAt(i) == " " || /[a-zA-Z.]/.test(string.charAt(i))) {
    ++i;
  }
  if (/[-|+]/.test(string.charAt(i))) {
    ++i;
  }
  if (!(/(\d)/.test(string.charAt(i)))) {
    var nOpen = 1;
    var nClose = 0;
    while (nOpen != nClose) {
      if (string.charAt(i + 1) == "(") {
        ++nOpen;
      } else if (string.charAt(i + 1) == ")") {
        ++nClose;
      }
      i += 1;
    }
    result = (string.substring(n + 1, i + 1));
  } else {
    while (/\d/.test(string.charAt(i)) || /[-|+|.]/.test(string.charAt(i))) {
      i += 1;
    }
    result = (string.substring(n + 1, i));
  }
  return result;
}

And so that it could be repeated and the function reached all the signs:

if (/\^/g.test(string)) {
  string = string.replace(/\s*\^\s*/g, "^")
  while (/\^/g.test(string)) {
    string = string.replace(captureBefore(string) + "^" + captureAfter(string), "Math.pow(" + captureBefore(string) + ", " + captureAfter(string) + ")");
  }
}

With that I was able to execute the function successfully. But if anyone has an idea that does the same thing with less code, I'm still open to possibilities.

working example

Scroll to Top