众所周知, C++标准库的std::string 如果用来处理字符串的话, 会很不友好,譬如使用字符串拆分split, 字符串数组组合啊, 字符串大小写转换之类的
本文讲述的是一些通过标准库现有接口实现的部分字符串操作方法
#include
int count(const std::string& string, const std::string& sep)
{
int cnt = 0;
std::string::size_type index = string.find(sep, 0);
while(index != std::string::npos) {
++cnt;
index = string.find(sep, index + sep.size());
}
return cnt;
}
std::vector<std::string> split(const std::string& string, const std::string& sep)
{
std::vector<std::string> result;
result.reserve(count(string, sep) + 1);
std::string::size_type start = 0;
std::string::size_type index = string.find(sep, start);
while(index != std::string::npos) {
result.push_back(string.substr(start, index - start));
start = index + sep.size();
index = string.find(sep, start);
}
result.push_back(string.substr(start));
return result;
}
std::vector<std::string> split_with_little_sep(const std::string& string, const std::string& sep)
{
std::vector<std::string> result;
std::string::size_type start = 0;
std::string::size_type index = string.find(sep, start);
while(index != std::string::npos) {
result.push_back(string.substr(start, index - start));
start = index + sep.size();
index = string.find(sep, start);
}
result.push_back(string.substr(start));
return result;
}
我这里写了两个版本, 从名字看, 第一种适合拆分分割的字符串出现次数比较多的情况, 第二种比较适合拆分分割字符串出现次数相当少或者没有的情况
#include
std::string join(const std::string& s, const std::vector<std::string>& v)
{
if(v.size() == 0) {
return std::string();
}
auto size = v.size() - 1;
std::ostringstream os;
for(auto i = 0u; i < size; ++i) {
os << v[i] << s;
}
os << v[size];
return os.str();
}
#include
#include
std::string lowerCase(const std::string& s)
{
std::string result(s);
std::transform(s.begin(), s.end(),
result.begin(),
[](unsigned char c) -> unsigned char {
return std::tolower (c);
} );
return result;
}
std::string upperCase(const std::string& s)
{
std::string result(s);
std::transform(s.begin(), s.end(),
result.begin(),
[](unsigned char c) -> unsigned char {
return std::toupper (c);
} );
return result;
}
// source: 原字符串也是结果字符串
// olds: 要替换的部分
// news: 替换后的内容
// times: 替换次数, -1 表示全部替换
void replace_self(std::string& source,
const std::string& olds,
const std::string& news,
int times = -1)
{
std::string::size_type index = source.find(olds);
while(index != std::string::npos && times) {
source.replace(index, olds.size(), news);
index = source.find(olds);
times = times > 0 ? times - 1 : times;
}
}
std::string replace(const std::string& source,
const std::string& olds,
const std::string& news
int times = -1)
{
std::string dest(source);
replace_self(dest, olds, news, times);
return dest;
}
bool startsWith(const std::string& source, const std::string& head)
{
return head.size() <= source.size()
&& source.compare(0, head.size(), head) == 0;
}
bool endsWith(const std::string& source, const std::string& tail)
{
return tail.size() <= source.size()
&& source.compare(source.size() - tail.size(), tail.size(), tail) == 0;
}
std::string trim(const std::string& source, const std::string& chars) {
std::string other(source);
auto start = other.find_first_of(chars);
auto end = other.find_first_not_of(chars, start);
while(start != npos) {
other.erase(start, end - start);
start = other.find_first_of(chars);
end = other.find_first_not_of(chars, start);
}
return other;
}