我目前正在使用以下代码在我的程序中右修剪所有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 <iostream>
#include <string>
#include <regex>
std::string ltrim( std::string str ) {
return std::regex_replace( str, std::regex("^\\s+"), std::string("") );
}
std::string rtrim( std::string str ) {
return std::regex_replace( str, std::regex("\\s+$"), std::string("") );
}
std::string trim( std::string str ) {
return ltrim( rtrim( str ) );
}
int main() {
std::string str = " \t this is a test string \n ";
std::cout << "-" << trim( str ) << "-\n";
return 0;
}
注意:我对c++还是个新手,所以如果我在这里离题了,请原谅。
其他回答
我的答案是对这篇文章的顶部答案的改进,它修剪了控制字符和空格(ASCII表上的0-32和127)。
isgraph确定一个字符是否有图形表示,因此您可以使用它来更改Evan的答案,以从字符串的两侧删除任何没有图形表示的字符。结果是一个更优雅的解决方案:
#include <algorithm>
#include <functional>
#include <string>
/**
* @brief Left Trim
*
* Trims whitespace from the left end of the provided std::string
*
* @param[out] s The std::string to trim
*
* @return The modified std::string&
*/
std::string& ltrim(std::string& s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
std::ptr_fun<int, int>(std::isgraph)));
return s;
}
/**
* @brief Right Trim
*
* Trims whitespace from the right end of the provided std::string
*
* @param[out] s The std::string to trim
*
* @return The modified std::string&
*/
std::string& rtrim(std::string& s) {
s.erase(std::find_if(s.rbegin(), s.rend(),
std::ptr_fun<int, int>(std::isgraph)).base(), s.end());
return s;
}
/**
* @brief Trim
*
* Trims whitespace from both ends of the provided std::string
*
* @param[out] s The std::string to trim
*
* @return The modified std::string&
*/
std::string& trim(std::string& s) {
return ltrim(rtrim(s));
}
注意:如果你需要支持宽字符,你也可以使用std::iswgraph,但是你也必须编辑这段代码来启用std::wstring操作,这是我还没有测试过的东西(请参阅std::basic_string的参考页面来探索这个选项)。
上面的方法很棒,但有时您想要使用函数组合来处理例程认为是空白的部分。在这种情况下,使用函子组合操作可能会变得混乱,所以我更喜欢一个简单的循环,我可以修改修剪。这里是一个稍微修改的修剪函数,从C版本复制到这里的SO。在这个例子中,我正在修剪非字母数字字符。
string trim(char const *str)
{
// Trim leading non-letters
while(!isalnum(*str)) str++;
// Trim trailing non-letters
end = str + strlen(str) - 1;
while(end > str && !isalnum(*end)) end--;
return string(str, end+1);
}
这是我想到的:
std::stringstream trimmer;
trimmer << str;
trimmer >> str;
流提取自动消除空白,所以这就像一个魅力。 要我说的话,也相当干净优雅。;)
下面是一个通道(可能是两个通道)的解决方案。它遍历字符串的空白部分两次,非空白部分一次。
void trim(std::string& s) {
if (s.empty())
return;
int l = 0, r = s.size() - 1;
while (l < s.size() && std::isspace(s[l++])); // l points to first non-whitespace char.
while (r >= 0 && std::isspace(s[r--])); // r points to last non-whitespace char.
if (l > r)
s = "";
else {
l--;
r++;
int wi = 0;
while (l <= r)
s[wi++] = s[l++];
s.erase(wi);
}
return;
}
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());
}