提取在括号和单引号之间使用单引号引起来的字符串 [英] extract a string with single quotes between parenthesis and single quote

查看:97
本文介绍了提取在括号和单引号之间使用单引号引起来的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

  #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 regex above is meant to extract everything between the single quotes.

但是我如何制作正则表达式,以便它能够提取转义的单引号(示例用户名(用户"5")应提取为用户5".

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'.

先谢谢了.我真的需要帮助.已经尝试了很多天了.

Thanks in advance. I really need help with this . Had been trying for so many days.

示例

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

找到了4个令牌.请注意,字符串周围的单引号应存在.预先感谢您的帮助.

There were 4 tokens found. Please note that the single quote around the string should be there. Thanks in advance for help.

但是现在如果我的字符串是

But now if my string is

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

输出应为:

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

推荐答案

但是我如何制作正则表达式,以便它能够提取转义的单引号(示例用户名(用户"5")应提取为用户5".

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'.

U.那是你的意思?我正确有关X/Y问题.

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. 重复此操作(例如printf("100%%");以打印100%)
  2. 使用另一个转义符(通常是反斜杠)来引入它.例如.

  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;

在这里:只需添加q >> char_(q)即可接受重复的引号作为引号转义:

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]; };

相对于 在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";
}

打印

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

这篇关于提取在括号和单引号之间使用单引号引起来的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆