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吗?
好的.您一直在询问有关6个问题的解析工作¹.
很多人一直在告诉你正则表达式不是这项工作的工具.包括我在内:
我告诉你了
我的所有示例都是优越的,因为它们已经将键和值一起解析,因此您有一个适当的配置设置图.
然而,你仍然在最新的问题中提出它(除了正则表达式中指定的内容之外,提取所有内容).
当然答案是我的第一个答案:
for (auto& setting : parse_config(text))
std::cout << setting.first << "\n";
Run Code Online (Sandbox Code Playgroud)
如果你因为不理解而拒绝它,你所要做的就是问.
如果你"不想"使用Spirit,你可以轻松地手动编写类似的解析器.我没有,因为它很乏味且容易出错.在这里,如果你需要灵感:
map<string, string>BOTTOM LINE:使用正确的语法,就像人们从第1天起就一直在催促你
#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)
¹看
Pes*_*ato -1
这里我们用另一个子字符串替换一个子字符串并返回修改后的字符串。我们传入要更改的字符串、要查找的字符串以及要替换为 、s和s_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)
#include <boost/algorithm/string/replace.hpp>
boost::replace_all(s, s_to_replace, s_replace);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
623 次 |
| 最近记录: |