我尝试在C ++ 11中创建类以计算以std :: string给出的数学公式。
std::string formula = "sqrt(3)+15*3*(2+3*4)+pow(2,3)+(2*(1+8))-(3*(1+pow(2,4)))";
我决定使用std :: regex搜索模式,将其获取,对其进行计算,并将其替换为计算结果。为了计算此公式,我制作了3种模式。
std::regex exprOne{ "[a-zA-Z0-9]+\\([^(),]+\\)" };
std::regex exprTwo{ "[a-zA-Z0-9]+\\([^()]+\\)" };
std::regex exprZero{ "(?![a-z0-9])\\([^(),]+\\)" };
exprOne匹配sqrt(3)
exprTwo匹配pow(2,3)
和pow(2,4)
但是exprZero的问题是它需要匹配(2+3*4)
和(1+8)
,但它也匹配sqrt(3)
。在互联网上,我在(?<![a-z0-9])
之后发现了回头路,但std :: regex却没有在互联网上找到的后门。有些人建议使用Boost.Regex,但我不想使用外部库。如果std :: regex没有向后看,您应该可以不使用它而做类似的事情?
exprZero不应与sqrt([^(),]+)
,log([^(),]+)
,log10([^(),]+)
等匹配,但应与([^(),]+)
匹配。
这是std :: regex中的一种模式吗?
您可以在此处使用非单词边界:
std::regex exprZero{R"(\B\([^(),]+\))"};
请参见regex demo
[\B\([^(),]+\)
模式将匹配(
,该字符串位于字符串的开头或紧接在非单词字符(字母,数字或_
以外的字符)之后,[^(),]+
将消耗(
,)
和,
以外的1个或多个字符,然后\)
将匹配)
字符。