代码之家  ›  专栏  ›  技术社区  ›  ssk

用于从字符串解析键/值对的Boost regex

  •  0
  • ssk  · 技术社区  · 5 年前

    我有以下字符串,正试图对其解析键值对:

    #include <iostream>
    #include <string>
    #include <map>
    
    #include <boost/regex.hpp>
    
    int main()
    {
        std::string deliveryReceipt = "id:pgl01130529155035239084 sub:001 dlvrd:001 submit date:1305291550 done date:1305291550 stat:DELIVRD err:0";
    
        std::map<std::string, std::string> results;
        boost::regex re("(?:([^:]+):([^,]+)(?:,|$))+"); // key - value pair
    
        boost::sregex_iterator it(deliveryReceipt.begin(), deliveryReceipt.end(), re), end;
        for ( ; it != end; ++it){
          results[(*it)[1]] = (*it)[2];
        }    
    
        std::map<std::string, std::string>::iterator resultsIter = results.begin();
        while (resultsIter != results.end())
        {
            std::cout << "key:" << resultsIter->first << " value:" << resultsIter->second << std::endl;
            resultsIter++;
        }
    }
    

    我得到以下输出:

    如何修复此正则表达式以正确解析键/值对?

    0 回复  |  直到 5 年前
        1
  •  3
  •   user557597 user557597    5 年前

    我要这样做( )

    "\\s*(?<!\\S)([^:]+)\\s*:(\\S+)(?!\\S)"

    https://regex101.com/r/Sufx5m/1

    解释

     \s*              # Optional whitespace trim
     (?<! \S)         # Whitespace boundary delimiter
                      #   (also matches at beginning of string)
     ( [^:]+ )        # (1), Key - not any ':' colon chars
     \s*              # Optional whitespace trim
     :                # Colon 
     ( \S+ )          # (2), Value - not whitespace chars
     (?! \S )         # Whitespace boundary delimiter.
                      #   (also matches at end of string)
    
        2
  •  1
  •   Emma    5 年前

    这个表情,

    (?<=^|\s)([^:]+):(\S*)(?=$|\s)
    

    (?<=^|\s)([^:]+):(\S*)
    

    可能可以从开始,您可以修改基于语言的转义。


    regex101.com . 如果你愿意,你也可以进去看 this link ,它将如何与一些示例输入匹配。


        3
  •  1
  •   The fourth bird    5 年前

    如果分隔符是 : : 您可以使用:

    \s*([^:]+):([^:\s]+)
    

    部分

    • \s* 匹配0+空格字符
    • (
    • ) 封闭组
    • : 逐字匹配
    • ( 捕获组2
      • [^:\s]+ : 或空白字符
    • ) 封闭组

    Regex demo

        4
  •  1
  •   sehe    5 年前

    现代C++允许比腐烂的正则表达式好得多的东西。

    您可以使用Boost Spirit在几行代码中编写强类型语法规范:

    using namespace boost::spirit::x3;
    auto key   = lexeme [ +(char_ - ':') ];
    auto value = lexeme [ +graph ];
    auto kvp   = lexeme [key >> ':' >> value];
    return skip(space) [ *kvp ];
    

    演示

    Live On Coliru

    #include <map>
    // for debug output only
    #include <iostream>
    #include <iomanip>
    
    // for parsing
    #include <boost/fusion/adapted/std_pair.hpp>
    #include <boost/spirit/home/x3.hpp>
    
    static inline auto kvp_parser() {
        using namespace boost::spirit::x3;
        auto key   = lexeme [ +(char_ - ':') ];
        auto value = lexeme [ +graph ];
        auto kvp   = lexeme [key >> ':' >> value];
        return skip(space) [ *kvp ];
    }
    
    int main() {
        std::string const deliveryReceipt = "id:pgl01130529155035239084 sub:001 dlvrd:001 submit date:1305291550 done date:1305291550 stat:DELIVRD err:0";
    
        std::map<std::string, std::string> results;
    
        parse(begin(deliveryReceipt), end(deliveryReceipt), kvp_parser(), results);
    
        for (auto& [k,v]: results) {
            std::cout << "key:" << std::quoted(k) << "\tvalue:" << std::quoted(v) << std::endl;
        }
    }
    

    key:"dlvrd" value:"001"
    key:"done date" value:"1305291550"
    key:"err"   value:"0"
    key:"id"    value:"pgl01130529155035239084"
    key:"stat"  value:"DELIVRD"
    key:"sub"   value:"001"
    key:"submit date"   value:"1305291550"