Search code examples
c++regexlookbehind

C++11 std::regex lookbehind alternative


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?


Solution

  • 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.