这看起来像是一个基本的问题,所以如果已经在某个地方得到回答我会道歉(我的搜索没有发现任何东西)。
我只想过滤一个字符串对象,使其只包含字母数字和空格字符。
这是我试过的:
#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()
个。
我在这里找不到一些明显的解决方案吗?
答案 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;
}
感谢埃里克·马林芬特(