C++ 如何使用C++/促进
这似乎是一个基本的问题,所以如果已经在某个地方得到了回答,我表示歉意(我的搜索没有找到任何结果) 我只想过滤字符串对象,使其只包含字母数字和空格字符 以下是我尝试过的:C++ 如何使用C++/促进,c++,string,boost,C++,String,Boost,这似乎是一个基本的问题,所以如果已经在某个地方得到了回答,我表示歉意(我的搜索没有找到任何结果) 我只想过滤字符串对象,使其只包含字母数字和空格字符 以下是我尝试过的: #include "boost/algorithm/string/erase.hpp" #include "boost/algorithm/string/classification.hpp" std::wstring oldStr = "Bla=bla =&*\nSampleSampleSample "; std::
#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\u all\u copy
的第二个参数中放入一个字符串,而不是这个是alnum()
的东西
有什么明显的解决方案我在这里遗漏了吗?我已经好几年没有使用boost了,但也许你可以用它来代替erase\u all\u 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 ]+"));
使用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)
));
std::wstring s=。。。
std::wstring new_s;
std::locale loc;
std::删除\复制\如果(s.开始()、s.结束()、std::返回\插入器(新的),
!(boost::bind(&std::isalnum,_1,loc)||
boost::bind(&std::isspace,_1,loc)
));
对于那些不那么明智的人,以下是基于@eric Malenfant答案的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;
}
std::string CleanString(const std::string&Input)
{
std::字符串清洁_字符串;
std::locale loc;
试一试{
std::remove_copy_if(Input.begin()、Input.end()、std::back_插入器(clean_string),
!(boost::bind(&std::isalnum,| 1,loc)| boost::bind(&std::isspace,|1,loc)
));
}
捕获(常数标准::错误分配和e){
std::我会收到关于字符和wchar_t转换的错误抱怨吗。也许这个正则表达式隐式地假设字符而不是wchar_t?我在正则表达式字符串前面放了一个L,但它也不喜欢。长错误消息的开头:C:\boost\u 1\u 40\u 0\boost/regex/v4/perl\u matcher\u common.hpp(802):警告C4244:“参数”:从“const wchar_t”转换为“char”,可能会丢失数据尝试将boost::regex(“etc”)更改为boost::regex(“etc”)?然后,Eric有一个很好的解决方案,可能不会给您带来同样的麻烦。:)(我自己也会测试这个代码,但是我的DEV机器上没有安装Boost…现在就建立/安装它),谢谢!在这一点上,它对我来说就像是一个黑魔法,但是它会给我一个开始理解迭代器和C++的更好的方法。@ Jijffe:ReaveWiSopiIf如果输入范围(S.Soin),s.end()“部分)和一个输出迭代器,它将提取的字符写入该迭代器(“back_inserter(new_s)”部分)。第四个参数是一个函数对象,它接受一个元素作为输入(在本例中为wchar_t)并返回bool。如果此函数返回true,则跳过该元素。(待续)这个函数对象是用boost::bind在这里创建的。“bind(&isalnum,_1,loc)”返回一个函数对象,该函数对象存储指向isalnum函数的指针和“loc”的副本。当用一个参数调用该函数对象时,它将依次调用isalnum(_参数,loc)最后,运算符重载魔术允许我们将C++中创建的两个函数对象与OR运算符组合起来,用非运算符否定它的结果。
#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;
}