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.