2012-11-28 86 views
1

我使用boost :: regex来解析某些格式化字符串,其中'%'符号是转义字符。因为我对boost :: regex没有多少经验,并且诚实地说正则表达式我会做一些试验和错误。这段代码是我想出来的一种原型。如何检查匹配哪个匹配组(boost-regex)

std::string regex_string = 
      "(?:%d\\{(.*)\\})|"     //this group will catch string for formatting time 
      "(?:%([hHmMsSqQtTlLcCxXmMnNpP]))|" //symbols that have some meaning 
      "(?:\\{(.*?)\\})|"     //some other groups 
      "(?:%(.*?)\\s)|" 
      "(?:([^%]*))"; 

    boost::regex regex; 
    boost::smatch match; 

    try 
    { 
     regex.assign(regex_string, boost::regex_constants::icase); 
     boost::sregex_iterator res(pattern.begin(), pattern.end(), regex); 
     //pattern in line above is string which I'm parsing 
     boost::sregex_iterator end; 
     for(; res != end; ++res) 
     { 
      match = *res; 
      output << match.get_last_closed_paren(); 
      //I want to know if the thing that was just written to output is from group describing time string 
      output << "\n"; 
     } 


    } 
    catch(boost::regex_error &e) 
    { 
     output<<"regex error\n"; 
    } 

而且这个工作非常好,在输出上我正是想要捕捉的东西。但我不知道它来自哪个组。我可以做一些类似match[index_of_time_group]!=""的东西,但这是一种脆弱的,看起来不太好。如果我更改regex_string指向组格式化时间的组捕获字符串的索引也可能发生更改。

有没有一个干净的方式来做到这一点?像命名组?我会很感激任何帮助。

回答

1

您可以使用boost::sub_match::matched布尔成员:

if(match[index_of_time_group].matched) process_it(match); 

也可以使用命名组在像正则表达式:(?<name_of_group>.*),以及与此上面的行可改为:

if(match["name_of_group"].matched) process_it(match); 
+0

谢谢!经过一番调整,我想出了以下解决方案。 我改变了一部分正则表达式:'(?:%d \\ {(?

+0

所以你可以接受点击绿色复选标记的答案。 – Rost

+0

5分钟打我,正在编辑几乎相同的代码:-) – Rost

0

动态从成对的名称/模式构建regex_string,并返回名称 - >索引映射以及正则表达式。然后编写一些代码来确定匹配是否来自给定名称。

如果你疯了,你可以在编译时(从标签到索引的映射)。这不值得。