如何使用C ++ / Boost过滤字符串中的字符

时间:2010-07-08 17:29:44

标签: c++ string boost

这看起来像是一个基本的问题,所以如果已经在某个地方得到回答我会道歉(我的搜索没有发现任何东西)。

我只想过滤一个字符串对象,使其只包含字母数字和空格字符。

这是我试过的:

#include "boost/algorithm/string/erase.hpp"
#include "boost/algorithm/string/classification.hpp"

std::wstring oldStr = "Bla=bla =&*\nSampleSampleSample ";
std::wstring newStr = boost::erase_all_copy(oldStr, !(boost::is_alnum() || 
                                                      boost::is_space()));

但编译器对此并不满意 - 似乎我只能在erase_all_copy的第二个参数中放入一个字符串而不是is_alnum()个。

我在这里找不到一些明显的解决方案吗?

3 个答案:

答案 0 :(得分:1)

我使用boost已经好几年了,但也许你可以使用erase_all_regex_copy()而不是erase_all_copy()?它可能会有点性能损失,但除了迭代每个元素并手动检查之外,它可能是您唯一的选择。如果你不熟悉正则表达式,那么你在这种情况下使用的表达式就像“[^ a-zA-Z0-9] +”。

为了完整起见,一些示例代码:

#include "boost/regex.hpp"
#include "boost/algorithm/string/regex.hpp"

std::wstring oldStr = "Bla=bla =&*\nSampleSampleSample ";
std::wstring newStr = boost::erase_all_regex_copy(oldStr, boost::regex("[^a-zA-Z0-9 ]+"));

答案 1 :(得分:1)

使用std算法和Boost.Bind:

std::wstring s = ...
std::wstring new_s;
std::locale loc;
std::remove_copy_if(s.begin(), s.end(), std::back_inserter(new_s), 
    !(boost::bind(&std::isalnum<wchar_t>, _1, loc)||
      boost::bind(&std::isspace<wchar_t>, _1, loc)
));

答案 2 :(得分:0)

对于那些不那么明智的人,这里是基于@ÉricMalenfant答案的ANSI和UNICODE函数:

std::string CleanString(const std::string& Input)
{
    std::string clean_string;
    std::locale loc;

    try {
        std::remove_copy_if(Input.begin(), Input.end(), std::back_inserter(clean_string),
            !(boost::bind(&std::isalnum<unsigned char>, _1, loc) || boost::bind(&std::isspace<unsigned char>, _1, loc)
        ));
    }
    catch (const std::bad_alloc& e) {
        std::cout << "Allocation failed: " << e.what() << '\n';
    }

    return clean_string;
}

std::wstring CleanString(const std::wstring& Input)
{
    std::wstring clean_string;
    std::locale loc;

    try {
        std::remove_copy_if(Input.begin(), Input.end(), std::back_inserter(clean_string),
            !(boost::bind(&std::isalnum<wchar_t>, _1, loc) ||
              boost::bind(&std::isspace<wchar_t>, _1, loc)
        ));
    } catch (const std::bad_alloc& e) {
        std::cout << "Allocation failed: " << e.what() << '\n';
    }
    return clean_string;
}

在线演示:https://wandbox.org/permlink/MFTwXV4ZCi9nsdlC

Linux的完整测试代码:

#include <iostream>
#include <algorithm>
#include <cctype>
#include <boost/bind.hpp>

// Note on Linux we use char and not unsigned char!
std::string CleanString(const std::string& Input)
{
    std::string clean_string;
    std::locale loc;

    try {
        std::remove_copy_if(Input.begin(), Input.end(), std::back_inserter(clean_string),
            !(boost::bind(&std::isalnum<char>, _1, loc) || boost::bind(&std::isspace<char>, _1, loc)
        ));
    }
    catch (const std::bad_alloc& e) {
        std::cout << "Allocation failed: " << e.what() << '\n';
    } 
    catch (...)
    {
    }

    return clean_string;
}

std::wstring CleanString(const std::wstring& Input)
{
    std::wstring clean_string;
    std::locale loc;

    try {
        std::remove_copy_if(Input.begin(), Input.end(), std::back_inserter(clean_string),
            !(boost::bind(&std::isalnum<wchar_t>, _1, loc) ||
              boost::bind(&std::isspace<wchar_t>, _1, loc)
        ));
    } 
    catch (const std::bad_alloc& e) {
        std::cout << "Allocation failed: " << e.what() << '\n';
    }
    catch (...)
    {
    }

    return clean_string;
}

int main()
{
    std::string test_1 = "Bla=bla =&*\n Sample Sample Sample !$%^&*@~";

    std::string new_test_1 = CleanString(test_1);

    if (!new_test_1.empty())
    {
        std::cout << "ANSI: " << new_test_1 << std::endl;
    }

    std::wstring test_uc_1 = L"!$%^&*@~ test &*";

    std::wstring new_test_uc_1 = CleanString(test_uc_1);

    if (!new_test_uc_1.empty())
    {
        std::wcout << L"UNICODE: " << new_test_uc_1 << std::endl;
    }

    return 0;
}

感谢埃里克·马林芬特(