C++ 正则表达式:使用求反方法搜索C+时,搜索不包含字符的组+;

C++ 正则表达式:使用求反方法搜索C+时,搜索不包含字符的组+;,c++,regex,string,C++,Regex,String,我正在使用默认的Visual Studio 2017社区版本。我刚刚完成了bignum实现的解析模型 我在向我的班级介绍公式时偶然发现了一个问题。这是一个字符串/正则表达式问题 考虑这个包含变量和常量的字符串: std::string formular_str = "1 + x * y / 2"; 将此字符串传递到解析函数中还需要int类型的向量(大小为2,因为有2个变量)(在本例中) formular\u str(“1+x*y/2”)现在看起来是这样的:“1+x*y/2” 接下来,我用递增索

我正在使用默认的Visual Studio 2017社区版本。我刚刚完成了bignum实现的解析模型 我在向我的班级介绍公式时偶然发现了一个问题。这是一个字符串/正则表达式问题

考虑这个包含变量和常量的字符串:

std::string formular_str = "1 + x * y / 2";
将此字符串传递到解析函数中还需要int类型的向量(大小为2,因为有2个变量)(在本例中)

formular\u str
“1+x*y/2”
)现在看起来是这样的:
“1+x*y/2”

接下来,我用递增索引替换所有变量(
x
y
)。 我在解析中使用
#
来表示
vec
的索引

std::regex reg_variable("[a-zA-Z]+[0-9]*");

unsigned ctr = 0;
while (std::regex_search(formular_str, reg_variable, std::regex_constants::format_first_only)) {
    formular_str = std::regex_replace(formular_str, reg_variable, std::string("#") + std::to_string(ctr++), std::regex_constants::format_first_only);
}
formular\u str
“1+x*y/2”
)现在看起来是这样的:
“1+#0*#1/2”

模型将正确地将
#0
#1
解释为
vec[0]
vec[1]

最后,我希望我的字符串和向量如下所示:

"#2+#0*#1/#3"
{5, 4, 1, 2}
但这里是预处理失败的地方。试图向后推()常量
1
2
到向量,并将其替换为
#2
#3
,而不会陷入无休止的循环

std::regex reg_constant("[^\\+\\-\\*\\/]+");
while (std::regex_search(formular_str, matches, reg_constant, std::regex_constants::format_first_only)) {
    //std::cout << "matches.str(0) = " << matches.str(0) << ", formular_str = " << formular_str << std::endl;
    vec.push_back(std::atoi(matches.str(0).c_str()));
    formular_str = std::regex_replace(formular_str, reg_constant, std::string("#") + std::to_string(ctr++), std::regex_constants::format_first_only);
}
第一场比赛是正确的,但它只是一直停留在第一个数字上。它甚至达不到
2
。因此,一个想法是将
#
视为操作符,并将其从匹配中排除:

std::regex reg_constant("[^\\+\\-\\*\\/\\#]+");
产生这种模式的原因是:

matches.str(0) = 1, formular_str = 1+#0*#1/2
matches.str(0) = 2, formular_str = #2+#0*#1/2
matches.str(0) = 3, formular_str = ##3+#0*#1/2
matches.str(0) = 4, formular_str = ###4+#0*#1/2
matches.str(0) = 5, formular_str = ####5+#0*#1/2
matches.str(0) = 6, formular_str = #####6+#0*#1/2
matches.str(0) = 7, formular_str = ######7+#0*#1/2
matches.str(0) = 8, formular_str = #######8+#0*#1/2
...
我还尝试了std::sregex_迭代器,但它也被卡住了。 我对此一无所知,我也考虑过在while循环中使用多层过滤和额外的
std::regex_search
std::regex_replace
,但它失败了,因为它不会改变公式以打破while循环。所以它必须是正则表达式来识别正确的字符串,但我似乎不能得到正确的结果。请帮帮我

完整代码(带有额外的std::couts)

#包括
#包括
#包括
int main(){
std::向量向量向量{5,4};
标准::字符串公式_str=“1+x*y/2”;

std::我建议使用不同的方法,如调车场或递归下降解析器。它们经过了很好的研究,并且很容易正确地工作(在您完成当前工作的部分后,您所采用的方法仍然需要类似的东西)。我已经完成了所有优先级规则/优先级等的解析。这只是关于字符串预处理。重点是,在解析时检索操作数并将其放在堆栈上要容易得多,而不是试图提前进行替换,并将正确的值作为参数传递。但这与此无关通过解析,它只需在字符串中替换组,而不会在需要帮助的地方卡住。也许我应该重新编写它。你是对的,但是让你的lexer检索(例如)
x
,只需在你的符号表中查找
x
的值,就可以轻松完成。
matches.str(0) = 1, formular_str = 1+#0*#1/2
matches.str(0) = #2, formular_str = #2+#0*#1/2
matches.str(0) = #3, formular_str = #3+#0*#1/2
matches.str(0) = #4, formular_str = #4+#0*#1/2
matches.str(0) = #5, formular_str = #5+#0*#1/2
matches.str(0) = #6, formular_str = #6+#0*#1/2
matches.str(0) = #7, formular_str = #7+#0*#1/2
matches.str(0) = #8, formular_str = #8+#0*#1/2
...
std::regex reg_constant("[^\\+\\-\\*\\/\\#]+");
matches.str(0) = 1, formular_str = 1+#0*#1/2
matches.str(0) = 2, formular_str = #2+#0*#1/2
matches.str(0) = 3, formular_str = ##3+#0*#1/2
matches.str(0) = 4, formular_str = ###4+#0*#1/2
matches.str(0) = 5, formular_str = ####5+#0*#1/2
matches.str(0) = 6, formular_str = #####6+#0*#1/2
matches.str(0) = 7, formular_str = ######7+#0*#1/2
matches.str(0) = 8, formular_str = #######8+#0*#1/2
...
#include <regex>
#include <string>
#include <iostream>

int main() {
    std::vector<int> vec{ 5, 4 };
    std::string formular_str = "1 + x * y / 2";

    std::cout << "Starting formular: " << formular_str << std::endl;

    std::smatch matches;
    std::regex reg_whitespace_near_operator("[\\s]+([\\+\\-\\*\\/])[\\s]+");
    while (std::regex_search(formular_str, matches, reg_whitespace_near_operator, std::regex_constants::format_first_only)) {
        formular_str = std::regex_replace(formular_str, reg_whitespace_near_operator, matches.str(1), std::regex_constants::format_first_only);
    }
    std::cout << "Whitespace removed: " << formular_str << std::endl;

    std::regex reg_variable("[a-zA-Z]+[0-9]*");

    unsigned ctr = 0;
    while (std::regex_search(formular_str, reg_variable, std::regex_constants::format_first_only)) {
        formular_str = std::regex_replace(formular_str, reg_variable, std::string("#") + std::to_string(ctr++), std::regex_constants::format_first_only);
    }

    std::cout << "Variables replaced: " << formular_str << std::endl;

    std::regex reg_constant("[^\\+\\-\\*\\/]+");
    while (std::regex_search(formular_str, matches, reg_constant, std::regex_constants::format_first_only)) {
        std::cout << "matches.str(0) = " << matches.str(0) << ", formular_str = " << formular_str << std::endl;
        vec.push_back(std::atoi(matches.str(0).c_str()));
        formular_str = std::regex_replace(formular_str, reg_constant, std::string("#") + std::to_string(ctr++), std::regex_constants::format_first_only);
    }

    std::cout << "Finished formular: " << formular_str << std::endl;
}