C++ 从字符串中删除前导和尾随空格

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1798112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:10:50  来源:igfitidea点击:

Removing leading and trailing spaces from a string

c++string

提问by Ankur

How to remove spaces from a string object in C++.
For example, how to remove leading and trailing spaces from the below string object.

如何从 C++ 中的字符串对象中删除空格。
例如,如何从下面的字符串对象中删除前导和尾随空格。

//Original string: "         This is a sample string                    "
//Desired string: "This is a sample string"

The string class, as far as I know, doesn't provide any methods to remove leading and trailing spaces.

据我所知,字符串类不提供任何方法来删除前导和尾随空格。

To add to the problem, how to extend this formatting to process extra spaces between words of the string. For example,

更重要的是,如何扩展此格式以处理字符串单词之间的额外空格。例如,

// Original string: "          This       is         a sample   string    " 
// Desired string:  "This is a sample string"  

Using the string methods mentioned in the solution, I can think of doing these operations in two steps.

使用解决方案中提到的字符串方法,我可以考虑分两步进行这些操作。

  1. Remove leading and trailing spaces.
  2. Use find_first_of, find_last_of, find_first_not_of, find_last_not_of and substr, repeatedly at word boundaries to get desired formatting.
  1. 删除前导和尾随空格。
  2. 使用find_first_of、find_last_of、find_first_not_of、find_last_not_of 和 substr,在单词边界处重复使用以获得所需的格式。

回答by GManNickG

This is called trimming. If you can use Boost, I'd recommend it.

这称为修剪。如果您可以使用Boost,我会推荐它。

Otherwise, use find_first_not_ofto get the index of the first non-whitespace character, then find_last_not_ofto get the index from the end that isn't whitespace. With these, use substrto get the sub-string with no surrounding whitespace.

否则,使用find_first_not_of获取第一个非空格字符find_last_not_of的索引,然后从不是空格的末尾获取索引。使用这些,用于substr获取没有周围空格的子字符串。

In response to your edit, I don't know the term but I'd guess something along the lines of "reduce", so that's what I called it. :) (Note, I've changed the white-space to be a parameter, for flexibility)

作为对您的编辑的回应,我不知道这个词,但我猜想一些类似于“减少”的东西,所以这就是我所说的。:)(注意,为了灵活性,我已将空格更改为参数)

#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;
}

Result:

结果:

[too much               space]  
[too much space]  
[too-much-space]  
[one  
two]  

回答by Evgeny Karpov

Easy removing leading, trailing and extra spaces from a std::string in one line

轻松从一行中的 std::string 中删除前导、尾随和额外空格

value = std::regex_replace(value, std::regex("^ +| +$|( ) +"), "");

removing only leading spaces

只删除前导空格

value.erase(value.begin(), std::find_if(value.begin(), value.end(), std::bind1st(std::not_equal_to<char>(), ' ')));

or

或者

value = std::regex_replace(value, std::regex("^ +"), "");

removing only trailing spaces

只删除尾随空格

value.erase(std::find_if(value.rbegin(), value.rend(), std::bind1st(std::not_equal_to<char>(), ' ')).base(), value.end());

or

或者

value = std::regex_replace(value, std::regex(" +$"), "");

removing only extra spaces

只删除多余的空格

value = regex_replace(value, std::regex(" +"), " ");

回答by Galik

I am currently using these functions:

我目前正在使用这些功能:

// 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);
}

回答by jon-hanson

Boost string trim algorithm

Boost字符串修剪算法

#include <boost/algorithm/string/trim.hpp>

[...]

std::string msg = "   some text  with spaces  ";
boost::algorithm::trim(msg);

回答by jha-G

Here is how you can do it:

您可以这样做:

std::string & trim(std::string & str)
{
   return ltrim(rtrim(str));
}

And the supportive functions are implemeted as:

支持功能实现为:

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;   
}

And once you've all these in place, you can write this as well:

一旦你准备好所有这些,你也可以这样写:

std::string trim_copy(std::string const & str)
{
   auto s = str;
   return ltrim(rtrim(s));
}

Try this

尝试这个

回答by Semjon M?ssinger

Example for trim leading and trailing spaces following jon-hanson's suggestion to use boost (only removes trailing and pending spaces):

在 jon-hanson 建议使用 boost 之后修剪前导和尾随空格的示例(仅删除尾随和挂起的空格):

#include <boost/algorithm/string/trim.hpp>

std::string str = "   t e s t    ";

boost::algorithm::trim ( str );

Results in "t e s t"

结果是 "t e s t"

There is also

还有

  • trim_leftresults in "t e s t "
  • trim_rightresults in " t e s t"
  • trim_left结果是 "t e s t "
  • trim_right结果是 " t e s t"

回答by Plamen Stoyanov

This is my solution for stripping the leading and trailing spaces ...

这是我剥离前导和尾随空格的解决方案......

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);

The result is "Plamen"

结果是“普拉门”

回答by Murphy78

/// 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);
}

In the above code, the isSpace() function is a boolean function that tells whether a character is a white space, you can implement this function to reflect your needs, or just call the isspace() from "ctype.h" if you want.

在上面的代码中,isSpace() 函数是一个布尔函数,它告诉我们一个字符是否是空格,你可以实现这个函数来反映你的需要,或者如果你想从“ctype.h”调用 isspace() .

回答by polfosol ?_?

Using the standard library has many benefits, but one must be aware of some special cases that cause exceptions. For example, none of the answers covered the case where a C++ string has some Unicode characters. In this case, if you use the function isspace, an exception will be thrown.

使用标准库有很多好处,但必须注意一些导致异常的特殊情况。例如,没有一个答案涵盖 C++ 字符串包含一些 Unicode 字符的情况。在这种情况下,如果使用函数isspace,则会抛出异常。

I have been using the following code for trimming the strings and some other operations that might come in handy. The major benefits of this code are: it is really fast (faster than any code I have ever tested), it only uses the standard library, and it never causes an exception:

我一直在使用以下代码来修剪字符串和其他一些可能会派上用场的操作。这段代码的主要好处是:它真的很快(比我测试过的任何代码都快),它只使用标准库,并且永远不会导致异常:

#include <string>
#include <algorithm>
#include <functional>
#include <locale>
#include <iostream>

typedef unsigned char BYTE;

std::string strTrim(std::string s, char option = 0)
{
    // convert all whitespace characters to a standard space
    std::replace_if(s.begin(), s.end(), (std::function<int(BYTE)>)::isspace, ' ');

    // remove leading and trailing spaces
    size_t f = s.find_first_not_of(' ');
    if (f == std::string::npos) return "";
    s = s.substr(f, s.find_last_not_of(' ') - f + 1);

    // remove consecutive spaces
    s = std::string(s.begin(), std::unique(s.begin(), s.end(),
        [](BYTE l, BYTE r){ return l == ' ' && r == ' '; }));

    switch (option)
    {
    case 'l':  // convert to lowercase
        std::transform(s.begin(), s.end(), s.begin(), ::tolower);
        return s;
    case 'U':  // convert to uppercase
        std::transform(s.begin(), s.end(), s.begin(), ::toupper);
        return s;
    case 'n':  // remove all spaces
        s.erase(std::remove(s.begin(), s.end(), ' '), s.end());
        return s;
    default: // just trim
        return s;
    }
}

回答by Thinkal VB

Example for trimming leading and trailing spaces

修剪前导和尾随空格的示例

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);

OR

或者

trimmedSring = aString.substr(aString.find_first_not_of(' '), (aString.find_last_not_of(' ') - aString.find_first_not_of(' ')) + 1);