问题描述
|
我正在编写一个软件,它要求我使用libcurl处理从网页中获取的数据。当我得到数据时,由于某种原因,它中有额外的换行符。我需要找出一种只允许使用字母,数字和空格的方法。并删除所有其他内容,包括换行符。有没有简单的方法可以做到这一点?谢谢。
解决方法
编写一个函数,取一个
char
,如果要删除该字符,则返回true
;如果要保留它,则返回false
:
bool my_predicate(char c);
然后使用std::remove_if
算法从字符串中删除不需要的字符:
std::string s = \"my data\";
s.erase(std::remove_if(s.begin(),s.end(),my_predicate),s.end());
根据您的要求,您也许可以使用标准库谓词之一(例如std::isalnum
),而不用编写自己的谓词(您说过您需要匹配字母数字字符和空格,因此也许这不完全符合您的要求。需要)。
如果要使用标准库std::isalnum
函数,则需要进行强制转换以消除C标准库标头<cctype>
中的std::isalnum
函数(这是您要使用的函数)和C ++标准库标头<locale>
中的std::isalnum
(除非要执行特定于语言环境的字符串处理,否则这不是您要使用的语言):
s.erase(std::remove_if(s.begin(),(int(*)(int))std::isalnum),s.end());
这对于任何序列容器(包括std::string
,std::vector
和std::deque
)同样有效。该惯用语通常称为“擦除/删除”惯用语。 std::remove_if
算法也适用于普通数组。 std::remove_if
仅对序列进行一次遍历,因此具有线性时间复杂度。
, 在没有传递一元参数的情况下,std::isalnum
的先前用法将无法与std::ptr_fun
一起编译,因此此具有lambda函数的解决方案应封装正确的答案:
s.erase(std::remove_if(s.begin(),[]( auto const& c ) -> bool { return !std::isalnum(c); } ),s.end());
, 如果您使用的是string
,则可以始终循环浏览并仅erase
所有非字母数字字符。
#include <cctype>
size_t i = 0;
size_t len = str.length();
while(i < len){
if (!isalnum(str[i]) || str[i] == \' \'){
str.erase(i,1);
len--;
}else
i++;
}
使用标准库的更好的人可能可以无循环执行此操作。
如果仅使用“ 0”缓冲区,则可以循环浏览,如果一个字符不是字母数字,则将所有字符向后移一个(以覆盖有问题的字符):
#include <cctype>
size_t buflen = something;
for (size_t i = 0; i < buflen; ++i)
if (!isalnum(buf[i]) || buf[i] != \' \')
memcpy(buf[i],buf[i + 1],--buflen - i);
, remove_copy_if标准算法非常适合您的情况。
, #include <cctype>
#include <string>
#include <functional>
std::string s = \"Hello World!\";
s.erase(std::remove_if(s.begin(),std::not1(std::ptr_fun(std::isalnum)),s.end()),s.end());
std::cout << s << std::endl;
结果是:
\"HelloWorld\"
您可以使用ѭ28determine来确定每个字符是否为字母数字,然后使用ptr_fun
将函数传递给not1
而不是返回值,只剩下所需的字母数字内容。
, 您可以通过这种方式使用删除-擦除算法-
// Removes all punctuation
s.erase( std::remove_if(s.begin(),&ispunct),s.end());
, 只是扩展了James McNellis的代码。他的功能是删除数字字符而不是非数字字符。
从字符串中删除非数字字符。 (数字=字母或数字)
声明一个函数(如果传递的字符不是数字,则isalnum返回0)
bool isNotAlnum(char c) {
return isalnum(c) == 0;
}
然后写这个
s.erase(remove_if(s.begin(),isNotAlnum),s.end());
那么您的字符串只能包含数字字符。
, 下面的代码对于给定的字符串34ѭ应该可以正常工作。它利用<algorithm>
和<locale>
库。
std::string s(\"He!!llo Wo,@rld! 12 453\");
s.erase(std::remove_if(s.begin(),[](char c) { return !std::isalnum(c); }),s.end());
, 以下对我有用。
str.erase(std::remove_if(str.begin(),str.end(),str.end());
str.erase(std::remove_if(str.begin(),&isspace),str.end());
, void remove_spaces(string data)
{ int i=0,j=0;
while(i<data.length())
{
if (isalpha(data[i]))
{
data[i]=data[i];
i++;
}
else
{
data.erase(i,1);}
}
cout<<data;
}
, 提到的解决方案
s.erase( std::remove_if(s.begin(),&std::ispunct),s.end());
很好,但不幸的是,由于此行,它在Visual Studio(调试模式)中不适用于\'Ñ\'等字符:
_ASSERTE((unsigned)(c + 1) <= 256)
在isctype.c中
所以,我建议这样的事情:
inline int my_ispunct( int ch )
{
return std::ispunct(unsigned char(ch));
}
...
s.erase( std::remove_if(s.begin(),&my_ispunct),s.end());