Doubt with Regex

3

Good evening.

I need a regular expression that can capture numbers / expressions before and after a given character, such as this ^ .

For example, in the string below I need it to return (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's important to check for only ^ .

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

    
asked by anonymous 21.12.2015 / 03:36

1 answer

0

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

I've got a way to do this, but it was not just with regex .

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

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

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

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

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

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

And to conclude, I should repeat this catching & capture> concatenation process until there was no more ^ left in the middle of the string . So I could have an exponentiation inside another exponentiation:

(2 ^ 3)^7

Javascript

To catch what was before ^ , 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 there 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 was repeated and the function reached all the signals:

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 this I was able to execute the function successfully. But if someone has an idea that has the same result with less code, I'm still open to possibilities.

Functional sample

    
26.12.2015 / 02:39