为什么Boost.Regex在一个字符串中找不到多个匹配项?

5 c++ regex boost

我正在编写一个小命令行程序,要求用户输入形式为ax ^ 2 + bx ^ 1 + cx ^ 0的多项式.我将稍后解析数据但是现在我只是想看看我是否可以将多项式与正则表达式匹配(\+|-|^)(\d*)x\^([0-9*]*)我的问题是,它与用户输入的多项式中的多个项不匹配,除非我更改它to ((\+|-|^)(\d*)x\^([0-9*]*))*(不同之处在于整个表达式被分组并在末尾有一个星号).如果我键入诸如" 4x^2"但不是" 4x^2+3x^1+2x^0"之类的东西,则第一个表达式有效,因为它不会多次检查.

我的问题是,为什么Boost.Regex不会regex_match()在同一个字符串中找到多个匹配?它在我使用的正则表达式编辑器(Expresso)中,但在实际的C++代码中没有.这应该是那样的吗?

如果事情没有意义,请告诉我,我会尽力澄清.谢谢您的帮助.

Edit1:这是我的代码(我在这里按照教程:http://onlamp.com/pub/a/onlamp/2006/04/06/boostregex.html?page = 3 )

int main()
{
    string polynomial;

    cmatch matches; // matches

    regex re("((\\+|-|^)(\\d*)x\\^([0-9*]*))*");

    cout << "Please enter your polynomials in the form ax^2+bx^1+cx^0." << endl;

    cout << "Polynomial:";
    getline(cin, polynomial);

    if(regex_match(polynomial.c_str(), matches, re))
    {
        for(int i = 0; i < matches.size(); i++)
        {
            string match(matches[i].first, matches[i].second);
            cout << "\tmatches[" << i << "] = " << match << endl;
        }
    }

    system("PAUSE");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Jer*_*fin 7

你使用的是错误的东西 - regex_match旨在检查(单个)正则表达式是否匹配整个字符序列.因此,您需要指定与整个输入匹配的正则表达式,或者使用其他内容.对于你的情况,你可能最有意义的是修改你正在使用的正则表达式(将它分组并添加一个Kleene星).如果你想迭代多项式的各个项,你可能想要使用类似的东西regex_token_iterator.

编辑:当然,既然你将它嵌入到C++中,你还需要将所有反斜杠加倍.看着它,我对你正在使用的正则表达式也有点困惑 - 它并不像我认为它应该真的很合适.例如,它似乎在一个术语的开头需要一个"+"," - "或"^",但第一个术语通常不会有.我也有点不确定为什么在一个学期开头会有一个"^".由于指数在零时通常被省略,因此最好允许它被省略.考虑到这些,我得到类似的东西:"[ - +]?(\ d*)x(\ ^([0-9])*)".

将它合并到一些代码中,我们可以得到这样的东西:

#include <iterator>
#include <regex>
#include <string>
#include <iostream>

int main() { 

    std::string poly = "4x^2+3x^1+2x";

    std::tr1::regex term("[-+]?(\\d*)x(\\^[0-9])*");

    std::copy(std::tr1::sregex_token_iterator(poly.begin(), poly.end(), term),
        std::tr1::sregex_token_iterator(), 
        std::ostream_iterator<std::string>(std::cout, "\n"));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

至少对我来说,每个术语都单独打印出来:

4x ^ 2
+ 3x ^ 1
+ 2x

请注意,目前,我刚刚打印出每个完整的术语,并修改了您的输入,以显示识别不包含权力的术语的能力(显然,无论如何).

编辑:要将结果收集到一个向量而不是发送到它std::cout,你会做这样的事情:

#include <iterator>
#include <regex>
#include <string>
#include <iostream>

int main() {   
    std::string poly = "4x^2+3x^1+2x";

    std::tr1::regex term("[-+]?(\\d*)x(\\^[0-9])*");
    std::vector<std::string> terms;

    std::copy(std::tr1::sregex_token_iterator(poly.begin(), poly.end(), term),
        std::tr1::sregex_token_iterator(), 
        std::back_inserter(terms));

    // Now terms[0] is the first term, terms[1] the second, and so on.

    return 0;
}
Run Code Online (Sandbox Code Playgroud)