2017-11-22 34 views
2

特殊な書式文字列の構文を解析する正規表現を書いてみたいと思います。これは、私がフォーマットエラーを検出し、フォーマット文字列を別の部分に分割して処理するのに役立ちます。C++ 11正規表現がグループを期待通りに返さない

しかし、試してみると難しいほど、分裂が期待どおりに機能することはありません。

'(?:)'構文では分割しないグループを定義する必要がありますが、通常の大括弧式 '()'では別々に返される部分一致を定義する必要があります。しかし、それはしません。ここで

は私のコードです:

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

std::string parseCode(std::regex_constants::error_type etype); 

int main() 
{ 
    const std::string regex_str("(?:([^\\[]+)(\\[[^\\]]*\\])(+|\\n))"); 
    std::regex atr; 

    std::cout << "regex string = '" << regex_str << "'" << std::endl; 

    try 
    { 
     atr.assign(regex_str); 
    } catch (const std::regex_error& e) 
    { 
     std::cerr << "Error: " << e.what() << "; code: " << parseCode(e.code()) << std::endl; 
     exit(EXIT_FAILURE); 
    } // end try 

    { 
     const std::string title("First Title[] Second Title[] -Third Title[]"); 
     auto regex_begin = std::sregex_iterator(title.begin(), title.end(), atr); 

     for (std::sregex_iterator i = regex_begin; i != std::sregex_iterator(); ++i) 
     { 
     std::smatch match = *i; 
     std::cout << "got: '" << match.str() << "'" << std::endl; 
     } // end for 

     auto subregex_begin = std::sregex_token_iterator(title.begin(), 
     title.end(), atr, -1); 

     for (std::sregex_token_iterator i = subregex_begin; i != std::sregex_token_iterator(); ++i) 
     { 
     std::cout << "got sub: '" << *i << "'" << std::endl; 
     } // end for 
    } // end scope 

} 

std::string parseCode(std::regex_constants::error_type etype) 
{ 

    switch (etype) 
    { 
    case std::regex_constants::error_collate: 
     return "error_collate: invalid collating element request"; 
    case std::regex_constants::error_ctype: 
     return "error_ctype: invalid character class"; 
    case std::regex_constants::error_escape: 
     return "error_escape: invalid escape character or trailing escape"; 
    case std::regex_constants::error_backref: 
     return "error_backref: invalid back reference"; 
    case std::regex_constants::error_brack: 
     return "error_brack: mismatched bracket([ or ])"; 
    case std::regex_constants::error_paren: 
     return "error_paren: mismatched parentheses((or))"; 
    case std::regex_constants::error_brace: 
     return "error_brace: mismatched brace({ or })"; 
    case std::regex_constants::error_badbrace: 
     return "error_badbrace: invalid range inside a { }"; 
    case std::regex_constants::error_range: 
     return "erro_range: invalid character range(e.g., [z-a])"; 
    case std::regex_constants::error_space: 
     return "error_space: insufficient memory to handle this regular expression"; 
    case std::regex_constants::error_badrepeat: 
     return "error_badrepeat: a repetition character (*, ?, +, or {) was not preceded by a valid regular expression"; 
    case std::regex_constants::error_complexity: 
     return "error_complexity: the requested match is too complex"; 
    case std::regex_constants::error_stack: 
     return "error_stack: insufficient memory to evaluate a match"; 
    default: 
     return ""; 
    } 
} 

そして、ここでは出力です:

regex string = '(?:([^\[]+)(\[[^\]]*\])(+))' 
got: 'First Title[] ' 
got: 'Second Title[] ' 
got sub: '' 
got sub: '' 
got sub: '-Third Title[]' 

そして、これは私が/期待したいものです。

regex string = '(?:([^\[]+)(\[[^\]]*\])(+))' 
got: 'First Title[] ' 
got: 'Second Title[] ' 
got: '-Third Title[]' 
got sub: 'First Title' 
got sub: '[]' 
got sub: ' ' 
got sub: 'Second Title' 
got sub: '[]' 
got sub: ' ' 
got sub: '-Third Title' 
got sub: '[]' 

私はG ++ 5.3.1を使用していますRHEL 7.2では
IdeOne.comでg ++ 6.3と同じ結果を得ました:https://ideone.com/dj4Mqf

私は間違っていますか? 、

全体マッチした文字列を返します match.str()
const std::string regex_str("([^\\[]+)(\\[[^\\]]*\\])(\\s+|\\n|$)"); 

2)、マッチした抽出物にグループoperator[]を使用します:

答えて

3

1)あなたの正規表現の最後の部分と一致していない、それを変更

std::smatch match = *i; 
    std::cout << "got: 1='" << match[1] << "' 2='" << match[2] << "' 3='" << match[3] << "'" << std::endl; 

出力:

regex string = '([^\[]+)(\[[^\]]*\])(\s+|\n|$)' 
got: 1='First Title' 2='[]' 3=' ' 
got: 1='Second Title' 2='[]' 3=' ' 
got: 1='-Third Title' 2='[]' 3='' 
関連する問題