How to replace ^ into calling Math.pow() ? For example:
str = "10 + 5.2^12"; // -> "10 + Math.pow(5.2, 12)"
str = "2^(12) + 6"; // -> "Math.pow(2, 12) + 6"
How to replace ^ into calling Math.pow() ? For example:
str = "10 + 5.2^12"; // -> "10 + Math.pow(5.2, 12)"
str = "2^(12) + 6"; // -> "Math.pow(2, 12) + 6"
You can do it like this:
str = str.replaceAll("\\(?(\\d+\\.?\\d*)\\)?\\^\\(?(\\d+\\.?\\d*)\\)?", "Math.pow($1,$2)");
In this case, you are looking for 2 groups of digits (\\d+\\.?\\d*)
, which could be a float value and can be inside of () \\(?
and \\)?
. Between this 2 groups, you need to have the ^ sign \\^
. If it matches, then replaceAll method replaces all this pattern with Math.pow($1,$2)
, where $1 and $2 will be replaced with first and second groups of digits.
But one thing, it could lead to wrong results if you have a complicated expression, with 2 multiplications in a row, like a 10.22^31.22^5
. In this case, this regular expression should be much more complicated. And may be you should use some other algorithm to parse such expressions.
You can do this with regular expression in java. Use the below code snippet to devide and replace the string.
private static String replaceMatchPow(String pValue) {
String regEx = "(\\d*\\.*\\d*)\\^\\(*(\\d*\\.*\\d*)\\)*";
Pattern pattern = Pattern.compile(regEx);
Matcher m = pattern.matcher(pValue);
if (m.find()) {
String value = "Math.pow(" + m.group(1) + "," + m.group(2) + ")";
pValue = pValue.replaceAll(regEx, value);
}
return pValue;
}
How the regex will work?
Here is the example for the input "2^(12) + 6"
1st group (\d*\.\d)
\d* -> match a digit [0-9],
* -> zero to unlimited
\^ -> divide the groups by ^ symbol
(* -> left bracket, * means occurrence zero to unlimited
2nd group (\d*\.\d)
)* -> right bracket
Result: 1st group values is 2 and 2nd group values is 12
/(\d*.*\d*)\^(*(\d*.*\d*))*/
1st Capturing group (\d*.*\d*)
\d* match a digit [0-9]
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
.* matches the character . literally
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
\d* match a digit [0-9]
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
\^ matches the character ^ literally
(* matches the character ( literally
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
2nd Capturing group (\d*.*\d*)
\d* match a digit [0-9]
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
.* matches the character . literally
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
\d* match a digit [0-9]
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
)* matches the character ) literally
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
For your special problem you should lookup how the caret character ^ is escaped in Java regular expressions, it should be \^
.
Note that:
Backslashes within string literals in Java source code are interpreted as required by The Java™ Language Specification as either Unicode escapes (section 3.3) or other character escapes (section 3.10.6) It is therefore necessary to double backslashes in string literals that represent regular expressions to protect them from interpretation by the Java bytecode compiler.
So you end up with "\\^"
as a Java String
.
However in general you will write a parser and interpreter for arithmetical expressions.
This subject is known as compiler construction and relies on knowledge of finite automata and formal languages.
A nice example can be found in chapter 10.2 "A Desk Calculator" of "The C++ Programming Language, Fourth Edition" by Bjarne Stroustrup. (Yes, I know you want to code in Java, please continue to read). It features this formal grammar:
program:
end //end is end-of-input
expr_list end
expr_list:
expression print //pr intis newline or semicolon
expression print expr_list
expression:
expression + term
expression − term
term
term:
term / primary
term ∗ primary
primary
primary:
number //number is a floating-point literal
name //name is an identifier
name = expression
−primary
( expression )
Stroustrup shows you how to code this in a similar structure:
double expr(bool get) //add and subtract
{
double left = term(get);
for(;;) { //‘‘forever’’
switch(ts.current().kind) {
case Kind::plus:
left += term(true);
break;
case Kind::minus:
left −= term(true);
break;
default:
return left;
}
}
}
this code embodies this part of the grammar:
expression:
expression + term
expression − term
term
This technique is called recursive descent, because recursion in the grammar will be implemented as a recursive function call in the corresponding code. The featured relevant C++ code should be understandable to a Java developer as well.
Once you got a bit familiar with grammars and how to implement them, see e.g. Unambiguous grammar for exponentiation operation how to deal with exponentiation in such a way, that the usual operator precedence rules are fulfilled.