从字符串中删除所有非字母字符。

5

有没有一种方法可以从 std::string 中删除所有非字母字符(例如,.?!等),同时不删除像ščéř这样的捷克符号? 我尝试使用:

std::string FileHandler::removePunctuation(std::string word) {
    for (std::string::iterator i = word.begin(); i != word.end(); i++) {
        if (!isalpha(word.at(i - word.begin()))) {
            word.erase(i);
            i--;
        }
    }
    return word;    
}

但它会删除捷克字符。

在最好的情况下,我想对这些符号也使用toLowerCase


1
尝试调整locale - StoryTeller - Unslander Monica
3
如果你想要按照函数名所示的那样删除标点符号,可以使用 std::ispunct 函数。 - molbdnilo
1
你正在使用哪种编码来处理 std::string?C++ 本身不支持 utf8,因此使用包含 utf8 数据的 std::string 不会按预期工作,因为字符串的每个元素都不对应于一个真实字符。如果正确提供区域设置,isalpha 可以与 std::wstringstd::u16string 一起使用。 - Jack
它很有帮助,但仍无法去除引号注释。 - Jakub Gruber
基本上,我想要删除除了字母数字字符以外的所有内容。 - Jakub Gruber
显示剩余2条评论
4个回答

3
你可以使用std::remove_iferase一起使用:
#include <cctype>
#include <algorithm>
#include <string>
//...
std::wstring FileHandler::removePunctuation(std::wstring word) 
{
    word.erase(std::remove_if(word.begin(), word.end(), 
                  [](char ch){ return !::iswalnum(ch); }), word.end());
    return word;
}

我通过小的修改尝试过了(将 !::iswalnum(ch) 更改为 ::ispunct(ch))。对于捷克语单词,它可以很好地工作,但是在使用 时我遇到了问题。 - Jakub Gruber
1
看起来左双引号(不是ASCII双引号)在你使用的语言环境中并不被视为标点符号。您可以替换或调整lambda以进行自己的检查,但答案是通常应该编写纠删码而不是循环的方式。 - PaulMcKenzie

2

这里有一个想法:

#include <iostream>
#include <cwctype>
// if windows, add this: #include <io.h>
// if windows, add this: #include <fcntl.h>

int main()
{
  // if windows, add this: _setmode( _fileno( stdout ), _O_U16TEXT );
  std::wstring s( L"š1č2é3ř!?" );
  for ( auto c : s )
    if ( std::iswalpha( c ) )
      std::wcout << c;
  return 0;
}

0
调用 std::setlocale(LC_ALL, "en_US.UTF-8") 后,您可以使用 std::iswalpha() 来判断某个字符是否为字母。
因此,下面的程序:
#include <cwctype>
#include <iostream>
#include <string>

int main()
{
    std::setlocale(LC_ALL, "en_US.UTF-8");
    std::wstring youreWelcome = L"Není zač.";

    for ( auto c : youreWelcome )
        if ( std::iswalpha(c) )
            std::wcout << c;

    std::wcout << std::endl;
}

将会打印

Nenízač

在控制台上回传。

请注意,std::setlocale() 本身可能不是线程安全的,也可能与其他同时执行的某些函数(如 std::iswalpha())结合使用时不是线程安全的。因此,它只应在单线程代码中使用,例如程序启动代码。更具体地说,您不应该从 FileHandler::removePunctuation() 中调用 std::setlocale(),而只有在需要时才调用 std::iswalpha()


-1

你可能需要编写一个自定义版本的isalpha函数。根据你的描述,它似乎只对a-z和A-Z返回true。


2
isalpha 使用当前语言环境。默认情况下,这意味着只有普通的英文字符。 - NathanOliver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接