How to strip all non alphanumeric characters from a string in c++?
我正在编写一个软件,它要求我使用libcurl处理从网页中获取的数据。 当我得到数据时,由于某种原因,它中有额外的换行符。 我需要找出一种只允许使用字母,数字和空格的方法。 并删除所有其他内容,包括换行符。 有没有简单的方法可以做到这一点? 谢谢。
编写一个接受
1 | bool my_predicate(char c); |
然后使用
1 2 | std::string s ="my data"; s.erase(std::remove_if(s.begin(), s.end(), my_predicate), s.end()); |
根据您的要求,您也许可以使用标准库谓词之一,例如
如果要使用标准库
1 | s.erase(std::remove_if(s.begin(), s.end(), (int(*)(int))std::isalnum), s.end()); |
这对于任何序列容器(包括
在没有传递一元参数的情况下,
1 2 | s.erase(std::remove_if(s.begin(), s.end(), []( auto const& c ) -> bool { return !std::isalnum(c); } ), s.end()); |
如果您使用的是
1 2 3 4 5 6 7 8 9 10 11 | #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++; } |
使用标准库的更好的人可能可以无循环执行此操作。
如果仅使用
1 2 3 4 5 6 | #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); |
1 2 3 4 5 6 7 8 | #include <cctype> #include <string> #include <functional> std::string s ="Hello World!"; s.erase(std::remove_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isalnum)), s.end()), s.end()); std::cout << s << std::endl; |
结果是:
1 | "HelloWorld" |
您使用
remove_copy_if标准算法非常适合您的情况。
下面的代码对于给定的字符串
1 2 | std::string s("He!!llo Wo,@rld! 12 453"); s.erase(std::remove_if(s.begin(), s.end(), [](char c) { return !std::isalnum(c); }), s.end()); |
只是扩展了James McNellis的代码。他的功能是删除数字字符而不是非数字字符。
从字符串中删除非数字字符。 (数字=字母或数字)
-
声明一个函数(如果传递的char不是alnum,则isalnum返回0)
1
2
3bool isNotAlnum(char c) {
return isalnum(c) == 0;
} -
然后写这个
1s.erase(remove_if(s.begin(), s.end(), isNotAlnum), s.end());
那么您的字符串只能包含数字字符。
您可以通过这种方式使用删除-擦除算法-
1 2 | // Removes all punctuation s.erase( std::remove_if(s.begin(), s.end(), &ispunct), s.end()); |
提到的解决方案
1 | s.erase( std::remove_if(s.begin(), s.end(), &std::ispunct), s.end()); |
非常好,但不幸的是不适用于'?'等字符在Visual Studio(调试模式)中,由于以下原因:
1 | _ASSERTE((unsigned)(c + 1) <= 256) |
在isctype.c中
所以,我建议这样的事情:
1 2 3 4 5 6 | inline int my_ispunct( int ch ) { return std::ispunct(unsigned char(ch)); } ... s.erase( std::remove_if(s.begin(), s.end(), &my_ispunct), s.end()); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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; } |
以下对我有用。
1 2 | str.erase(std::remove_if(str.begin(), str.end(), &ispunct), str.end()); str.erase(std::remove_if(str.begin(), str.end(), &isspace), str.end()); |