What's the best way to trim std::string?

后端 未结 30 2879
无人及你
无人及你 2020-11-21 22:13

I\'m currently using the following code to right-trim all the std::strings in my programs:

std::string s;
s.erase(s.find_last_not_of(\" \\n\\r\\         


        
相关标签:
30条回答
  • 2020-11-21 22:55

    The above methods are great, but sometimes you want to use a combination of functions for what your routine considers to be whitespace. In this case, using functors to combine operations can get messy so I prefer a simple loop I can modify for the trim. Here is a slightly modified trim function copied from the C version here on SO. In this example, I am trimming non alphanumeric characters.

    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);
    }
    
    0 讨论(0)
  • 2020-11-21 22:56

    Hacked off of Cplusplus.com

    std::string choppa(const std::string &t, const std::string &ws)
    {
        std::string str = t;
        size_t found;
        found = str.find_last_not_of(ws);
        if (found != std::string::npos)
            str.erase(found+1);
        else
            str.clear();            // str is all whitespace
    
        return str;
    }
    

    This works for the null case as well. :-)

    0 讨论(0)
  • 2020-11-21 22:56

    With C++11 also came a regular expression module, which of course can be used to trim leading or trailing spaces.

    Maybe something like this:

    std::string ltrim(const std::string& s)
    {
        static const std::regex lws{"^[[:space:]]*", std::regex_constants::extended};
        return std::regex_replace(s, lws, "");
    }
    
    std::string rtrim(const std::string& s)
    {
        static const std::regex tws{"[[:space:]]*$", std::regex_constants::extended};
        return std::regex_replace(s, tws, "");
    }
    
    std::string trim(const std::string& s)
    {
        return ltrim(rtrim(s));
    }
    
    0 讨论(0)
  • 2020-11-21 22:57

    Using Boost's string algorithms would be easiest:

    #include <boost/algorithm/string.hpp>
    
    std::string str("hello world! ");
    boost::trim_right(str);
    

    str is now "hello world!". There's also trim_left and trim, which trims both sides.


    If you add _copy suffix to any of above function names e.g. trim_copy, the function will return a trimmed copy of the string instead of modifying it through a reference.

    If you add _if suffix to any of above function names e.g. trim_copy_if, you can trim all characters satisfying your custom predicate, as opposed to just whitespaces.

    0 讨论(0)
  • 2020-11-21 22:57

    My answer is an improvement upon the top answer for this post that trims control characters as well as spaces (0-32 and 127 on the ASCII table).

    std::isgraph determines if a character has a graphical representation, so you can use this to alter Evan's answer to remove any character that doesn't have a graphical representation from either side of a string. The result is a much more elegant solution:

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

    Note: Alternatively you should be able to use std::iswgraph if you need support for wide characters, but you will also have to edit this code to enable std::wstring manipulation, which is something that I haven't tested (see the reference page for std::basic_string to explore this option).

    0 讨论(0)
  • 2020-11-21 22:57
    s.erase(0, s.find_first_not_of(" \n\r\t"));                                                                                               
    s.erase(s.find_last_not_of(" \n\r\t")+1);   
    
    0 讨论(0)
提交回复
热议问题