如何从C ++中的正则表达式中提取部分?

时间:2014-01-22 15:11:02

标签: c++ c++11

如何在C ++中从正则表达式中提取部件?

例如,我有这样的模式:

new line means "followed by"

delimiter string,
name,
':' character,
list of Xs, where X is name; (string followed by ';' character)

我可以使用正则表达式进行匹配,但有没有办法不仅匹配, 还要从模式中提取部分?例如:

$DatasetName: A; B; C;

是给定的字符串,我想提取数据集名称, 然后列名为A,B和C.

1 个答案:

答案 0 :(得分:1)

嗯,正如已经建议的那样,您可以手动解析类似于此(它仅用于演示目的,并不声称是完美的):

#include <iostream>
#include <vector>
#include <string>

bool parse_by_hand(const std::string& phrase)
{
    enum parse_state
    {
        parse_name,
        parse_value,
    };
    std::string name, current_value;
    std::vector<std::string> values;
    parse_state state = parse_name;
    for(std::string::const_iterator iterator = phrase.begin(); iterator != phrase.end(); iterator++)
    {
        switch(state)
        {
        case parse_name:
            if(*iterator != ':')
                name += *iterator;
            else 
                state = parse_value;
            break;
        case parse_value:
            if(*iterator != ';')
                current_value += *iterator;
            else 
            {
                state = parse_value;
                values.push_back(current_value);
                current_value.clear();
            }
            break;
        default:
            return false;
        }
    }
    // Error checking here, name parsed? values parsed?
    return true;
}

int main(int argc, char** argv)
{
    std::string phrase("$DatasetName: A; B; C;");
    parse_by_hand(phrase);
}

关于std::regex,我的第一个镜头是针对这样的([^:]*):(([^;]*);)*,但除非我没有弄错(我希望有人在我这里纠正我),递归捕获小组会给出你最后一个匹配的值不是所有的值,所以你仍然需要用regex_search进行多次迭代,这样可以减少表中'one-liner-regex-matching'的难易程度。或者,如果std::regex不是必须的并且您可以使用Boost,请查看Repeated captures,这应该可以解决捕获组问题。