如何从c ++中的字符串中删除所有非字母数字字符?

Aus*_*oon 23 c++ string alphanumeric strip libcurl

我正在编写一个软件,它要求我处理从libcurl网页获得的数据.当我获得数据时,由于某种原因,它有额外的换行符.我需要想办法只允许字母,数字和空格.并删除其他所有内容,包括换行符.有没有简单的方法来做到这一点?谢谢.

Jam*_*lis 43

编写一个函数,如果要删除该字符或者如果要保留它char,则返回并返回:truefalse

bool my_predicate(char c);
Run Code Online (Sandbox Code Playgroud)

然后使用该std::remove_if算法从字符串中删除不需要的字符:

std::string s = "my data";
s.erase(std::remove_if(s.begin(), s.end(), my_predicate), s.end());
Run Code Online (Sandbox Code Playgroud)

根据您的要求,您可以使用标准库谓词之一std::isalnum,而不是编写自己的谓词(您说您需要匹配字母数字字符和空格,所以这可能不完全符合您的需要) .

如果要使用标准库std::isalnum函数,则需要使用强制转换来消除std::isalnumC标准库标题<cctype>(您要使用的std::isalnum标题)中的函数与C++标准库标题<locale>(不是那个标题库)中的函数之间的歧义.你想要使用,除非你想执行特定于语言环境的字符串处理):

s.erase(std::remove_if(s.begin(), s.end(), (int(*)(int))std::isalnum), s.end());
Run Code Online (Sandbox Code Playgroud)

这同样适用与任何序列容器(包括std::string,std::vectorstd::deque).这种习语通常被称为"擦除/删除"习语.该std::remove_if算法也适用于普通数组.在std::remove_if仅使单个传过来的序列,因此它具有线性时间复杂度.

  • 这样做,不是我的. (6认同)
  • `(int(*)(int))std::isalnum` 将只保留特殊字符,而是使用 `std::not1(std::ptr_fun( (int(*)(int))std::isalnum )) ` 反转其逻辑 (3认同)
  • @James:它正在删除字母数字字符而不是特殊字符.难道我做错了什么 ? (2认同)
  • 它将删除字母数字字符而不是特殊字符,因为只要遇到字母数字字符,`(int(*)(int))std :: isalnum`将返回"true",并且该字符将从字符串中删除. (2认同)

Dad*_*ado 10

以前的使用std::isalnum不会在std::ptr_fun没有传递一元参数的情况下编译,因此这个带有lambda函数的解决方案应该封装正确的答案:

s.erase(std::remove_if(s.begin(), s.end(), 
[]( auto const& c ) -> bool { return !std::isalnum(c); } ), s.end());
Run Code Online (Sandbox Code Playgroud)


Set*_*gie 5

你可以通过始终循环只是erase,如果你正在使用的所有非字母数字字符string

#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++;
}
Run Code Online (Sandbox Code Playgroud)

更好地使用标准库的人可能可以在没有循环的情况下做到这一点。

如果您只使用char缓冲区,则可以循环遍历,如果字符不是字母数字,则将其后的所有字符向后移动一个(以覆盖有问题的字符):

#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);
Run Code Online (Sandbox Code Playgroud)


Ali*_*lik 5

只是稍微扩展了 James McNellis 的代码。他的功能是删除alnum字符而不是非alnum字符。

从字符串中删除非数字字符。(alnum = 字母或数字)

那么你的字符串只包含 alnum 字符。