用单引号(')替换双引号('')

hyd*_*123 5 c++ string boost replace

假设我有一个字符串:

argsStr = "server ('m1.labs.terad  ''ata.com') username ('us ''er5') password('user)5') dbname ('def\\ault')";
Run Code Online (Sandbox Code Playgroud)

现在我使用以下代码来提取令牌:

'm1.labs.terad  ''ata.com'  <- token1
'us ''er5'                    <-token2
'user)5'                    <-token3
'def\ault'                  <-token4
Run Code Online (Sandbox Code Playgroud)

码:

regex re("(\'(.*?)\'\)");
typedef std::vector<std::string> StringVector;
StringVector arg_values;
boost::regex re_arg_values("('[^']*(?:''[^']*)*')");
boost::sregex_token_iterator name_iter_start(argsStr.begin(),argsStr.end(), re_arg_values, 0),name_iter_end;
std::copy(value_iter_start, value_iter_end,std::back_inserter(arg_values)); 
//putting the token in the string vector.
Run Code Online (Sandbox Code Playgroud)

将它放入字符串向量后,如何转换标记/字符串以用单引号替换双引号:

例如:

'm1.labs.terad ''ata.com' 应该成为'm1.labs.terad 'ata.com'并且 'us ''er5' 应该成为'us 'er5'.

我可以使用boost :: replace_all吗?

seh*_*ehe 7

好的.您一直在询问有关6个问题的解析工作¹.

很多人一直在告诉你正则表达式不是这项工作的工具.包括我在内:

在此输入图像描述

我告诉你了

  • Spirit X3语法的一个示例,它将此配置字符串解析为键值映射,正确解释转义的引号('\\''例如)(请参阅此处)
  • 我扩展它(13个字符)以允许重复引用以逃避引用(请参阅此处)

我的所有示例都是优越的,因为它们已经将键和值一起解析,因此您有一个适当的配置设置图.

然而,你仍然在最新的问题中提出它(除了正则表达式中指定的内容之外,提取所有内容).

当然答案是我的第一个答案:

for (auto& setting : parse_config(text))
    std::cout << setting.first << "\n";
Run Code Online (Sandbox Code Playgroud)

在Coliru上发布了这个以及C++ 03版本

编写手动解析器

如果你因为不理解而拒绝它,你所要做的就是问.

如果你"不想"使用Spirit,你可以轻松地手动编写类似的解析器.我没有,因为它很乏味且容易出错.在这里,如果你需要灵感:

  1. 还是c ++ 03
  2. 仅使用标准库功能
  3. 仍使用可谓的引号解析单引号/双引号字符串
  4. 仍在解析 map<string, string>
  5. 在无效输入上引发信息性错误消息

BOTTOM LINE:使用正确的语法,就像人们从第1天起就一直在催促你

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";
    }
}
Run Code Online (Sandbox Code Playgroud)

打印一如既往:

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
Run Code Online (Sandbox Code Playgroud)

¹看

  1. 避免在cpp中使用空标记
  2. 在cpp中使用正则表达式提取空格
  3. 正则表达式使用boost令牌迭代器在单引号和括号之间提取值
  4. 标记字符串,接受CPP中给定字符集之间的所有内容
  5. 在括号和单引号之间提取带单引号的字符串
  6. 提取除正则表达式中指定的内容之外的所有内容
  7. 这个


Pes*_*ato -1

使用 For 循环将子字符串替换为字符串中的子字符串

这里我们用另一个子字符串替换一个子字符串并返回修改后的字符串。我们传入要更改的字符串、要查找的字符串以及要替换为 、ss_to_replace的字符串s_replace

find()搜索并找到传入字符串的第一个字符,并返回该位置的迭代器。std::string::npos该值是可以达到的最大可能值size_t,即字符串的末尾。std::string::erase获取第一个字符的位置和要替换的字符数并删除它们。std::string::insert获取插入位置和要插入的字符串的位置并执行此操作。

std::string replace_substring(string s, const string s_to_replace, const string s_replace) {
    for(size_t position = 0; ; position += s_replace.length()) {

        position = s.find(s_to_replace, position);

        if(position == string::npos || s.empty()) break;

        s.erase(position, s_to_replace.length());
        s.insert(position, s_replace);
        // s.replace(position, s_to_replace.length(), s_replace)
    }
    return s;
}
Run Code Online (Sandbox Code Playgroud)

使用 Boost 将子字符串替换为字符串中的子字符串

#include <boost/algorithm/string/replace.hpp>

boost::replace_all(s, s_to_replace, s_replace);
Run Code Online (Sandbox Code Playgroud)