如何在C++中从字符串对象中删除空格.
例如,如何从下面的字符串对象中删除前导和尾随空格.
//Original string: " This is a sample string "
//Desired string: "This is a sample string"
Run Code Online (Sandbox Code Playgroud)
据我所知,字符串类没有提供任何删除前导和尾随空格的方法.
要添加问题,如何扩展此格式以处理字符串的单词之间的额外空格.例如,
// Original string: " This is a sample string "
// Desired string: "This is a sample string"
Run Code Online (Sandbox Code Playgroud)
使用解决方案中提到的字符串方法,我可以考虑分两步执行这些操作.
GMa*_*ckG 117
这称为修剪.如果你可以使用Boost,我会推荐它.
否则,使用find_first_not_of
获取第一个非空白字符find_last_not_of
的索引,然后从不是空白的结尾获取索引.使用这些,用于substr
获取没有周围空白的子字符串.
为了回应你的编辑,我不知道这个术语,但我猜的是"减少"的东西,所以这就是我所说的.:)(注意,我已将白色空间更改为参数,以获得灵活性)
#include <iostream>
#include <string>
std::string trim(const std::string& str,
const std::string& whitespace = " \t")
{
const auto strBegin = str.find_first_not_of(whitespace);
if (strBegin == std::string::npos)
return ""; // no content
const auto strEnd = str.find_last_not_of(whitespace);
const auto strRange = strEnd - strBegin + 1;
return str.substr(strBegin, strRange);
}
std::string reduce(const std::string& str,
const std::string& fill = " ",
const std::string& whitespace = " \t")
{
// trim first
auto result = trim(str, whitespace);
// replace sub ranges
auto beginSpace = result.find_first_of(whitespace);
while (beginSpace != std::string::npos)
{
const auto endSpace = result.find_first_not_of(whitespace, beginSpace);
const auto range = endSpace - beginSpace;
result.replace(beginSpace, range, fill);
const auto newStart = beginSpace + fill.length();
beginSpace = result.find_first_of(whitespace, newStart);
}
return result;
}
int main(void)
{
const std::string foo = " too much\t \tspace\t\t\t ";
const std::string bar = "one\ntwo";
std::cout << "[" << trim(foo) << "]" << std::endl;
std::cout << "[" << reduce(foo) << "]" << std::endl;
std::cout << "[" << reduce(foo, "-") << "]" << std::endl;
std::cout << "[" << trim(bar) << "]" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
结果:
[too much space]
[too much space]
[too-much-space]
[one
two]
Run Code Online (Sandbox Code Playgroud)
Evg*_*pov 44
轻松地从一行中的std :: string中删除前导,尾随和额外空格
value = std::regex_replace(value, std::regex("^ +| +$|( ) +"), "$1");
Run Code Online (Sandbox Code Playgroud)
仅删除前导空格
value.erase(value.begin(), std::find_if(value.begin(), value.end(), std::bind1st(std::not_equal_to<char>(), ' ')));
Run Code Online (Sandbox Code Playgroud)
要么
value = std::regex_replace(value, std::regex("^ +"), "");
Run Code Online (Sandbox Code Playgroud)
仅删除尾随空格
value.erase(std::find_if(value.rbegin(), value.rend(), std::bind1st(std::not_equal_to<char>(), ' ')).base(), value.end());
Run Code Online (Sandbox Code Playgroud)
要么
value = std::regex_replace(value, std::regex(" +$"), "");
Run Code Online (Sandbox Code Playgroud)
只删除额外的空格
value = regex_replace(value, std::regex(" +"), " ");
Run Code Online (Sandbox Code Playgroud)
Gal*_*lik 38
我目前正在使用这些功能:
// trim from left
inline std::string& ltrim(std::string& s, const char* t = " \t\n\r\f\v")
{
s.erase(0, s.find_first_not_of(t));
return s;
}
// trim from right
inline std::string& rtrim(std::string& s, const char* t = " \t\n\r\f\v")
{
s.erase(s.find_last_not_of(t) + 1);
return s;
}
// trim from left & right
inline std::string& trim(std::string& s, const char* t = " \t\n\r\f\v")
{
return ltrim(rtrim(s, t), t);
}
// copying versions
inline std::string ltrim_copy(std::string s, const char* t = " \t\n\r\f\v")
{
return ltrim(s, t);
}
inline std::string rtrim_copy(std::string s, const char* t = " \t\n\r\f\v")
{
return rtrim(s, t);
}
inline std::string trim_copy(std::string s, const char* t = " \t\n\r\f\v")
{
return trim(s, t);
}
Run Code Online (Sandbox Code Playgroud)
jon*_*son 19
#include <boost/algorithm/string/trim.hpp>
[...]
std::string msg = " some text with spaces ";
boost::algorithm::trim(msg);
Run Code Online (Sandbox Code Playgroud)
C++17 引入了std::basic_string_view
,一个类模板,它引用类似 char 的对象的常量连续序列,即字符串的视图。除了与 非常相似的界面外std::basic_string
,它还有两个附加功能:remove_prefix()
,通过向前移动起始点来缩小视图;和
remove_suffix()
,通过向后移动其末端来缩小视图。这些可用于修剪前导和尾随空格:
#include <string_view>
#include <string>
std::string_view ltrim(std::string_view str)
{
const auto pos(str.find_first_not_of(" \t\n\r\f\v"));
str.remove_prefix(std::min(pos, str.length()));
return str;
}
std::string_view rtrim(std::string_view str)
{
const auto pos(str.find_last_not_of(" \t\n\r\f\v"));
str.remove_suffix(std::min(str.length() - pos - 1, str.length()));
return str;
}
std::string_view trim(std::string_view str)
{
str = ltrim(str);
str = rtrim(str);
return str;
}
int main()
{
std::string str = " hello world ";
auto sv1{ ltrim(str) }; // "hello world "
auto sv2{ rtrim(str) }; // " hello world"
auto sv3{ trim(str) }; // "hello world"
//If you want, you can create std::string objects from std::string_view objects
std::string s1{ sv1 };
std::string s2{ sv2 };
std::string s3{ sv3 };
}
Run Code Online (Sandbox Code Playgroud)
注意:使用 来std::min
确保pos
不大于size()
,当字符串中的所有字符都是空格并find_first_not_of
返回时,就会发生这种情况npos
。此外,std::string_view
是一个非拥有引用,因此仅当原始字符串仍然存在时它才有效。修剪字符串视图对其所基于的字符串没有影响。
以下是如何做到这一点:
std::string & trim(std::string & str)
{
return ltrim(rtrim(str));
}
Run Code Online (Sandbox Code Playgroud)
支持功能的实现如下:
std::string & ltrim(std::string & str)
{
auto it2 = std::find_if( str.begin() , str.end() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
str.erase( str.begin() , it2);
return str;
}
std::string & rtrim(std::string & str)
{
auto it1 = std::find_if( str.rbegin() , str.rend() , [](char ch){ return !std::isspace<char>(ch , std::locale::classic() ) ; } );
str.erase( it1.base() , str.end() );
return str;
}
Run Code Online (Sandbox Code Playgroud)
一旦你完成所有这些,你也可以这样写:
std::string trim_copy(std::string const & str)
{
auto s = str;
return ltrim(rtrim(s));
}
Run Code Online (Sandbox Code Playgroud)
试试这个
小智 7
这是我剥离前导和尾随空格的解决方案......
std::string stripString = " Plamen ";
while(!stripString.empty() && std::isspace(*stripString.begin()))
stripString.erase(stripString.begin());
while(!stripString.empty() && std::isspace(*stripString.rbegin()))
stripString.erase(stripString.length()-1);
Run Code Online (Sandbox Code Playgroud)
结果是"Plamen"
在jon-hanson建议使用boost之后修剪前导空格和尾随空格的示例(仅删除尾随空格和待处理空格):
#include <boost/algorithm/string/trim.hpp>
std::string str = " t e s t ";
boost::algorithm::trim ( str );
Run Code Online (Sandbox Code Playgroud)
结果是 "t e s t"
还有
trim_left
结果是 "t e s t "
trim_right
结果是 " t e s t"
/// strip a string, remove leading and trailing spaces
void strip(const string& in, string& out)
{
string::const_iterator b = in.begin(), e = in.end();
// skipping leading spaces
while (isSpace(*b)){
++b;
}
if (b != e){
// skipping trailing spaces
while (isSpace(*(e-1))){
--e;
}
}
out.assign(b, e);
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,isSpace() 函数是一个布尔函数,它告诉我们一个字符是否是空格,你可以实现这个函数来反映你的需要,或者如果你想从“ctype.h”调用 isspace() .
修剪前导空格和尾随空格的示例
std::string aString(" This is a string to be trimmed ");
auto start = aString.find_first_not_of(' ');
auto end = aString.find_last_not_of(' ');
std::string trimmedString;
trimmedString = aString.substr(start, (end - start) + 1);
Run Code Online (Sandbox Code Playgroud)
或者
trimmedSring = aString.substr(aString.find_first_not_of(' '), (aString.find_last_not_of(' ') - aString.find_first_not_of(' ')) + 1);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
173690 次 |
最近记录: |