我目前正在使用以下代码在我的程序中右修剪所有std::字符串:
std::string s;
s.erase(s.find_last_not_of(" \n\r\t")+1);
它工作得很好,但我想知道是否有一些最终情况下它可能会失败?
当然,有优雅的选择和左修剪解决方案的答案是受欢迎的。
我目前正在使用以下代码在我的程序中右修剪所有std::字符串:
std::string s;
s.erase(s.find_last_not_of(" \n\r\t")+1);
它工作得很好,但我想知道是否有一些最终情况下它可能会失败?
当然,有优雅的选择和左修剪解决方案的答案是受欢迎的。
当前回答
下面是一个用正则表达式进行修整的解决方案
#include <string>
#include <regex>
string trim(string str){
return regex_replace(str, regex("(^[ ]+)|([ ]+$)"),"");
}
其他回答
http://ideone.com/nFVtEo
std::string trim(const std::string &s)
{
std::string::const_iterator it = s.begin();
while (it != s.end() && isspace(*it))
it++;
std::string::const_reverse_iterator rit = s.rbegin();
while (rit.base() != it && isspace(*rit))
rit++;
return std::string(it, rit.base());
}
我想如果你开始询问修剪字符串的“最佳方式”,我会说一个好的实现将是:
不分配临时字符串 有过载的地方修剪和复制修剪 可以很容易地定制接受不同的验证序列/逻辑
显然,有太多不同的方法来解决这个问题,这绝对取决于你真正需要什么。然而,C标准库在<string.h>中仍然有一些非常有用的函数,比如memchr。C仍然被认为是IO的最佳语言是有原因的——它的标准库是纯粹的效率。
inline const char* trim_start(const char* str)
{
while (memchr(" \t\n\r", *str, 4)) ++str;
return str;
}
inline const char* trim_end(const char* end)
{
while (memchr(" \t\n\r", end[-1], 4)) --end;
return end;
}
inline std::string trim(const char* buffer, int len) // trim a buffer (input?)
{
return std::string(trim_start(buffer), trim_end(buffer + len));
}
inline void trim_inplace(std::string& str)
{
str.assign(trim_start(str.c_str()),
trim_end(str.c_str() + str.length()));
}
int main()
{
char str [] = "\t \nhello\r \t \n";
string trimmed = trim(str, strlen(str));
cout << "'" << trimmed << "'" << endl;
system("pause");
return 0;
}
因为我想用c++ 11的方法更新我的旧c++修剪函数,我已经测试了很多关于这个问题的答案。我的结论是,我保留了旧的c++解决方案!
它是总体上最快的一个,即使添加更多的字符来检查(例如\r\n我没有看到\f\v的用例)仍然比使用算法的解决方案更快。
std::string & trimMe (std::string & str)
{
// right trim
while (str.length () > 0 && (str [str.length ()-1] == ' ' || str [str.length ()-1] == '\t'))
str.erase (str.length ()-1, 1);
// left trim
while (str.length () > 0 && (str [0] == ' ' || str [0] == '\t'))
str.erase (0, 1);
return str;
}
这太烦人了,我
必须谷歌它 发现我必须使用火箭科学 字符串中没有简单的trim/toupper函数
对我来说,这是最快的解决方法:
CString tmp(line.c_str());
tmp = tmp.Trim().MakeLower();
string buffer = tmp;
我可以使用lambda ops,迭代器,以及所有的东西,这很酷。但我只需要处理一个字符串而不是一个字符…
下面是一个简单的实现。对于这样一个简单的操作,您可能不应该使用任何特殊的构造。内置的isspace()函数负责处理各种形式的白色字符,因此我们应该充分利用它。您还必须考虑字符串为空或只是一堆空格的特殊情况。向左或向右修剪可以从下面的代码派生。
string trimSpace(const string &str) {
if (str.empty()) return str;
string::size_type i,j;
i=0;
while (i<str.size() && isspace(str[i])) ++i;
if (i == str.size())
return string(); // empty string
j = str.size() - 1;
//while (j>0 && isspace(str[j])) --j; // the j>0 check is not needed
while (isspace(str[j])) --j
return str.substr(i, j-i+1);
}