Extract single quote string between brackets and single quote

I have the following code:

#include <iostream> #include <regex> using namespace std; int main() { string s; s = "server ('m1.labs.terad ata.com') username ('us er5') password('user)5') dbname ('def\\ault')"; regex re("(\'(.*?)\'\)"); sregex_token_iterator i(s.begin(), s.end(), re, 1); sregex_token_iterator j; unsigned count = 0; while(i != j) { cout <<*i<< endl; count++; i++; } cout << "There were " << count << " tokens found." << endl; return 0; } 

the above expression is intended to highlight everything between single quotes.

But how can I create a regular expression so that it can extract single quotes (for example, the username (user''5) should be extracted as "user'5".

Thanks in advance. I really need help with this. Spent so many days.

Example

 'm1.labs.terad ata.com' 'us er5' 'user)5' 'def\ault' 

4 tokens were found. Note that the single quotation mark around the string should be there. Thanks in advance for your help.

But now if my line

  s = "server ('m1.labs.terad ata.com') username ('us ''er5') password('user)5') dbname ('def\\ault')"; 

The output should be:

  'm1.labs.terad ata.com' 'us 'er5' <<<<<<<<<<<<<<<<<<< 'user)5' 'def\ault' 
+1
source share
2 answers

But how can I create a regular expression so that it can extract single quotes (for example, the username (user''5) should be extracted as "user'5".

Ugh. Is that what you meant ? I was right about the X / Y issues.

Note What you describe is called escaping special characters . Two common ways to avoid special characters are:

  • repeat it (for example, printf("100%%"); to print 100% )
  • enter it using another escape (usually a backslash). For instance.

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

    Or another complex example:

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

Here you go: just add q >> char_(q) to accept duplicate quotes like quot-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 with respect to the tokenizing string, taking everything between a 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"; } 

Print

 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 
+2
source

You should look look-around and conditional regexp.
And the regex engine must be PCRE compatible. (I do not know about C ++)

You should use the new regexp expression that you found on the Internet if you do not understand it.

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

0
source

Source: https://habr.com/ru/post/1270130/


All Articles