Good. You asked a question about these syntactic tasks on 6 questions directly.
Many people have told you that regular expression is not a tool for work. Including me :

I showed you
- An example of a Spirit X3 grammar that parses this configuration line in a key value map, correctly interpreting escaped quotes (
'\\'' eg) (see here ) - I expanded it (in 13 characters) to allow repeated quotes to avoid quotation (see here )
All my examples were excellent in that they already parse the keys along with the values, so you have the right map of configuration settings.
However, you still ask for it in your last question ( Extract everything except what is indicated in the regular expression ).
Of course, the answer was in my very first answer:
for (auto& setting : parse_config(text)) std::cout << setting.first << "\n";
I posted this along with my C ++ 03 version live on Coliru
Writing a Handheld Analyzer
If you reject it because you do not understand, all you have to do is ask.
If you don't want to use Spirit, you can easily write a similar parser manually. I did not do this because it is tiring and error prone. Here you are in case you need it for inspiration:
- more C ++ 03
- using only standard library functions
- still parsing single / double quotes with escalation quotes
- still parsing on
map<string, string> - causes informative error messages when invalid input
BOTTOM LINE : Use the correct grammar as people have been calling you from day one.
Live on coliru
#include <iostream> #include <sstream> #include <map> typedef std::map<std::string, std::string> Config; typedef std::pair<std::string, std::string> Entry; struct Parser { Parser(std::string const& input) : input(input) {} Config parse() { Config parsed; enum { KEY, VALUE } state = KEY; key = value = ""; f = input.begin(), l = input.end(); while (f!=l) { //std::cout << "state=" << state << ", '" << std::string(It(input.begin()), f) << "[" << *f << "]" << std::string(f+1, l) << "'\n"; switch (state) { case KEY: skipws(); if (!parse_key()) raise("Empty key"); state = VALUE; break; case VALUE: if (!expect('(', true)) raise("Expected '('"); if (parse_value('\'') || parse_value('"')) { parsed[key] = value; key = value = ""; } else { raise("Expected quoted value"); } if (!expect(')', true)) raise("Expected ')'"); state = KEY; break; }; } if (!(key.empty() && value.empty() && state==KEY)) raise("Unexpected end of input"); return parsed; } private: std::string input; typedef std::string::const_iterator It; It f, l; std::string key, value; bool parse_key() { while (f!=l && alpha(*f)) key += *f++; return !key.empty(); } bool parse_value(char quote) { if (!expect(quote, true)) return false; while (f!=l) { char const ch = *f++; if (ch == quote) { if (expect(quote, false)) { value += quote; } else { //std::cout << " Entry " << key << " -> " << value << "\n"; return true; } } else { value += ch; } } return false; } static bool space(unsigned char ch) { return std::isspace(ch); } static bool alpha(unsigned char ch) { return std::isalpha(ch); } void skipws() { while (f!=l && space(*f)) ++f; } bool expect(unsigned char ch, bool ws = true) { if (ws) skipws(); if (f!=l && *f == ch) { ++f; if (ws) skipws(); return true; } return false; } void raise(std::string const& msg) { std::ostringstream oss; oss << msg << " (at '" << std::string(f,l) << "')"; throw std::runtime_error(oss.str()); } }; int main() { std::string const text = "server ('m1.labs.terad ''ata.com') username ('us\\* er5') password('user)5') dbname ('def\\ault')"; Config cfg = Parser(text).parse(); for (Config::const_iterator setting = cfg.begin(); setting != cfg.end(); ++setting) { std::cout << "Key " << setting->first << " has value " << setting->second << "\n"; } for (Config::const_iterator setting = cfg.begin(); setting != cfg.end(); ++setting) { std::cout << setting->first << "\n"; } }
Printing, as always:
Key dbname has value def\ault Key password has value user)5 Key server has value m1.labs.terad 'ata.com Key username has value us\* er5 dbname password server username
ยน see