在c ++中删除标点符号和空格的最佳方法是什么?

时间:2013-10-10 17:31:01

标签: c++ string

为了从给定的字符串中删除空格和标点符号。使用正则表达式匹配似乎是一种方法,但使用bool数组[256]并将标点符号和空格的值设置为true将是有效的。此外,由于这将被多次调用,最好将其用作静态数组,但如何在char数组中将punctions和space的值设置为true?就像写一个单独的静态方法那样做?

3 个答案:

答案 0 :(得分:3)

如果你有C ++ 11,你可以使用lambda轻松完成。

s.erase(
    std::remove_if(
        s.begin(), s.end(),
        []( unsigned char ch ) { return isspace( ch ) || ispunct( ch ); } ),
    s.end() );

这使用当前的全局区域设置。

没有C ++ 11,你必须定义一个功能对象 (如果你这么做的话,可以重复使用):

struct IsSpaceOrPunct
{
    bool operator()( unsigned char ch ) const
    {
        return isspace( ch ) || ispunct( ch );
    }
};

并使用它的一个实例代替C ++中的lambda 表达

这两个都使用is...中的<ctype.h>函数(即{} 为什么他们在unsigned char上运作 - 调用这些 具有char的函数是未定义的行为。)

更通用的解决方案更多的是:

template <std::ctype_base::mask m>
class Is
{
    std::locale l;  //  To ensure lifetime of the following...
    std::ctype<char> const* ctype;
public:
    Is( std::locale const& l = std::locale() )
        : l( l )
        , ctype( &std::use_facet<std::ctype<char>>( l ) )
    {
    }
    bool operator()( char ch ) const
    {
        return is( m, ch );
    }
};

typedef Is<std::ctype_base::space | std::ctype_base::punct> IsSpaceOrPunct;

对于简单的应用程序之一,这是过度的(除非你 确实需要支持不同的语言环境),但如果你这样做 任何大量的文本处理,你一定会想要的 拥有它。由于模板,你可以得到各种各样的 几乎没有工作的断言,只是另一种typedef。

答案 1 :(得分:2)

提供的两个答案将起作用,但这种方法不需要转换函数指针:

std::string text = "some text, here and there.  goes up; goes down";
std::string result;
std::remove_copy_if(text.begin(), text.end(), std::back_inserter(result), [](char c)
{
    std::locale loc;
    return std::ispunct(c, loc) || std::isspace(c, loc);
}); 

答案 2 :(得分:0)

std::remove_copy_ifstd::ispunct

一起使用
string text ="some text with punctuations",result;
std::remove_copy_if(text.begin(), text.end(),            
                        std::back_inserter(result), //Store output           
                        std::ptr_fun<int, int>(&std::ispunct)  
                       );