【问题标题】:Retaining just needed characters in string in C++在 C++ 中的字符串中保留刚需要的字符
【发布时间】:2015-04-07 09:45:20
【问题描述】:

我有一个形式的字符串:

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

现在我想从这个字符串中删除除字母数字和://之外的所有字符。所以输出字符串变为:

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

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

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

我使用的 gcc 版本是: gcc (GCC) 4.4.7 20120313 (红帽 4.4.7-4)

编辑:我还想包含 á 之类的字符。我不知道他们叫什么。我知道它们不是字母数字。但我不知道如何检查它们

【问题讨论】:

  • C 还是 C++?或两者?您的标题仅提及 C++

标签: c++ c regex string gcc


【解决方案1】:

由于您的编译器很古老,并且 gcc 中的正则表达式支持相对较新(从 gcc 4.9 开始),因此不能选择正则表达式。我们将使用 erase-remove idiom 和命名函数,因为 Gcc 4.4 尚不支持 lambda。

#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';
}

【讨论】:

  • "á"。我有像“á”这样的字符。它们不是字母数字,但我想保留它们,如何在我的 is_special_character 函数中指定它
  • 您可以使用std::locale 和使用它的std::isalnum 重载(请参阅编辑)。您必须输入(与系统相关的)语言环境字符串才能使其正常工作。您也可以手动检查字符,但这会比较乏味。 (顺便说一句,你可能还想保留.;我在它的时候把它放进去了)
  • 我对我的问题进行了一点修改。我很抱歉更新晚了
  • 您的语言环境是什么?另外:字符串是如何编码的?
  • 字符串是 UNICODE 编码的。我找到了我的语言环境: string s= std::locale("").name().c_str() ;
【解决方案2】:

您将需要使用 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

【讨论】:

  • "á"。我有像“á”这样的字符。它们不是字母数字,但我想保留它们,如何在我的 is_special_character 函数中指定它
  • 我添加了一个使用语言环境和 wstrings 来支持 unicode 字符的示例。
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

    你可以试试这样的:

    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."
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-15
      • 2021-01-31
      • 2019-02-13
      • 2022-01-17
      • 1970-01-01
      • 2021-03-26
      • 2011-12-04
      相关资源
      最近更新 更多