在C++中保留字符串中的刚需字符

Retaining just needed characters in string in C++

本文关键字:字符 保留字 C++ 保留 字符串      更新时间:2023-10-16

我有一个形式为的字符串

http://stackoverflow.com/q""uestions/ask/%33854@/á

现在我想从这个字符串中删除除alphnumeric和://之外的所有字符。这样输出字符串就变成了:

http://stackoverflow.com/questions/ask/33854/á

我知道我可以逐个字符遍历这个字符串,并删除不必要的字符。但是,在一些标准库中是否有一些功能可以帮助我删除不需要的字符。如果我知道不需要的字符,那么我可以使用std::remove和std::replace来选择性地删除或替换。但在这里,我不知道未知的字符,我只知道我想保留的字符。

有没有什么方法可以让我只保留必要的字符并删除不需要的字符。

我使用的gcc版本是:gcc(gcc)4.4.7 20120313(Red Hat 4.4.7-4)

编辑:我也想加入像á这样的角色。我不知道它们叫什么。我知道它们不是字母数字。但我不知道如何检查它们

由于您的编译器很古老,而且regex支持在gcc中相对较新(从gcc 4.9向前),因此regex不是一个选项。由于Gcc4.4还不支持lambdas,我们将使用带有命名函数的擦除-删除习惯用法。

#include <algorithm>
#include <iostream>
#include <locale>
#include <string>
// true for characters that should be removed
bool is_special_character(char c) {
  std::locale loc("your_locale_string_here");
  return !std::isalnum(c, loc) && c != ':' && c != '/' && c != '.';
}
int main()
{
  std::string s = "http://stackoverflow.com/q""uestions/ask/%33854@";
  // interesting part here
  s.erase(std::remove_if(s.begin(), s.end(), is_special_character), s.end());
  std::cout << s << 'n';
}

您将希望使用std::remove_if,并定义一个谓词,仅当字符是您想要保留的字符时才返回false。

在完成此过程后,您还需要将字符串调整为新的长度。例如:

#include <string>
#include <algorithm>
#include <iostream>
#include <locale>
bool is_special_char(char c)
{
    return !( std::isalnum(c) || c == ':' || c == '/' || c == '.');
}
int main()
{
    std::string s = "http://stackoverflow.com/q""uestions/ask/%33854@";
    std::cout << s << std::endl;
    std::string::iterator new_end = std::remove_if(s.begin(), s.end(), is_special_char);
    s.resize(new_end - s.begin());
    std::cout << s << std::endl;
}

将输出

http://stackoverflow.com/q""uestions/ask/%33854@
http://stackoverflow.com/questions/ask/33854

如果你想合并unicode字符,你需要使用wstring而不是字符串,一个使用这个的例子(并结合了Wintermute对擦除/删除习惯用法的巧妙使用)是。

#include <string>
#include <algorithm>
#include <iostream>
#include <locale>
bool is_special_char(wchar_t c)
{
    return !( std::iswalnum(c) || c == ':' || c == '/' || c == '.');
}
int main()
{
    std::locale::global( std::locale("en_US.UTF-8") ); //Set the global locale to Unicode
    std::wstring s = L"http://stáckoverflow.com/q""uestions/ask/%33854@";
    std::wcout << s << std::endl;
    s.erase( std::remove_if(s.begin(), s.end(), is_special_char), s.end() );
    std::wcout << s << std::endl;
}

将输出

http://stáckoverflow.com/q""uestions/ask/%33854@
http://stáckoverflow.com/questions/ask/33854

但在这里,我不知道未知的字符,我只知道我想保留的字符。

例如,使用char数组将要保留的字符列为白名单。然后遍历字符串中的每个字符,如果它不在白名单中,则将其删除。

你可以试试这样的东西:

std::string str ("This is an example sentence.");
   std::cout << str << 'n';
                                           // "This is an example sentence."
   str.erase (10,8);                        //            ^^^^^^^^ 
   std::cout << str << 'n';
                                           // "This is an sentence."
   str.erase (str.begin()+9);               //           ^
   std::cout << str << 'n';
                                           // "This is a sentence."
   str.erase (str.begin()+5, str.end()-9);  //       ^^^^^
   std::cout << str << 'n';
                                           // "This sentence."