I try to make class in C++11 to calculate math formula given as std::string.
std::string formula = "sqrt(3)+15*3*(2+3*4)+pow(2,3)+(2*(1+8))-(3*(1+pow(2,4)))";
I have decided to use std::regex to search for patterns, take them, calculate them and replace them with calculation result. To calculate this formula I made 3 patterns.
std::regex exprOne{ "[a-zA-Z0-9]+\\([^(),]+\\)" };
std::regex exprTwo{ "[a-zA-Z0-9]+\\([^()]+\\)" };
std::regex exprZero{ "(?![a-z0-9])\\([^(),]+\\)" };
exprOne matches sqrt(3)
exprTwo matches pow(2,3)
and pow(2,4)
but problem are with exprZero it needs to match (2+3*4)
and (1+8)
, but it matches sqrt(3)
too. On internet I found lookbehind (?<![a-z0-9])
, but std::regex don't have lookbehind as I found on internet. Some suggest to use Boost.Regex, but I want to not use external libraries. If std::regex don't have lookbehind you should be able to do similar thing not using it?
exprZero should not match sqrt([^(),]+)
, log([^(),]+)
, log10([^(),]+)
and so on, but should match ([^(),]+)
.
Is here a pattern in std::regex to do it?
You may use a non-word boundary here:
std::regex exprZero{R"(\B\([^(),]+\))"};
See the regex demo
The \B\([^(),]+\)
pattern will match a (
that is either at the start of a string or right after a non-word char (a char other than a letter, digit or _
), [^(),]+
will consume 1 or more chars other than (
, )
and ,
and then \)
will match a )
char.