extract a string with single quotes between parenthesis and single quote

后端 未结 2 411
Happy的楠姐
Happy的楠姐 2021-01-16 06:21

I have the following code :

  #include 
#include 

using namespace std;

int main()
{
  string s;

      s = \"server (\'m1.labs         


        
相关标签:
2条回答
  • 2021-01-16 06:49

    You should look at look-around and conditional regexp.
    And regex engine should be PCRE compatible. (I don't know about C++)

    You should newer use regexp, you have found in the internet if you dont understand it.

    Try something like '((?:[^']|'')*?)'(?!') (demo on 101regex)

    0 讨论(0)
  • 2021-01-16 07:13

    But how can I make the regex so that it is able to extract escaped single quotes (example username (user''5) should be extracted as 'user'5'.

    Ugh. Is that what you meant? I was right about X/Y problem then.

    Note: What you describe is known as escaping special characters. Two common ways to escape special characters:

    1. repeat it (e.g. printf("100%%"); to print 100%)
    2. introduce it using another escape (usually backslash). E.g.

      std::cout << "Hello \"World\"" << std::endl;
      

      Or, one more intricate example:

      std::cout << "Newline is \\n" << std::endl;
      

    Here you go: just add q >> char_(q) to accept repeated quotes as quote-escape:

    auto quoted = [](char q) { 
        return lexeme[ q >> *(
                  q >> char_(q)  // accept repeated quotes as quote-escape
                | '\\' >> char_  // accept backs-slash escape
                | char_ - q      // accept any other non-quote
             ) >> q]; };
    

    Nothing else changes relative to tokenizing string , accepting everything between given set of characters in CPP

    Live On Coliru

    #include <iostream>
    #include <boost/spirit/home/x3.hpp>
    #include <boost/fusion/adapted/std_pair.hpp>
    #include <map>
    
    using Config = std::map<std::string, std::string>;
    using Entry  = std::pair<std::string, std::string>;
    
    namespace parser {
        using namespace boost::spirit::x3;
    
        template <typename T> auto as = [](auto p) { return rule<struct _, T> {} = p; };
        auto quoted = [](char q) { return lexeme[q >> *(q >> char_(q) | '\\' >> char_ | char_ - q) >> q]; };
    
        auto value  = quoted('\'') | quoted('"');
        auto key    = lexeme[+alpha];
        auto pair   = key >> '(' >> value >> ')';
        auto config = skip(space) [ *as<Entry>(pair) ];
    }
    
    Config parse_config(std::string const& cfg) {
        Config parsed;
        auto f = cfg.begin(), l = cfg.end();
        if (!parse(f, l, parser::config, parsed))
            throw std::invalid_argument("Parse failed at " + std::string(f,l));
        return parsed;
    }
    
    int main() {
        auto const text = "server ('m1.labs.teradata.com') username ('use'')r_*5') password('u\" er 5') dbname ('default')";
        Config cfg = parse_config(text);
    
        for (auto& setting : cfg)
            std::cout << "Key " << setting.first << " has value " << setting.second << "\n";
    }
    

    Prints

    Key dbname has value default
    Key password has value u" er 5
    Key server has value m1.labs.teradata.com
    Key username has value use')r_*5
    
    0 讨论(0)
提交回复
热议问题