使用ispunct()删除标点符号

Removing punctuation marks using ispunct()

本文关键字:删除 标点符号 ispunct 使用      更新时间:2023-10-16

ispunct()在单词以这种方式"one, two; three"分隔时工作良好。然后它将删除",;"并替换为给定的字符。

但如果字符串以这种方式给定"ts='TOK_STORE_ID';",那么它将把"ts='TOK_STORE_ID';"作为一个单独的令牌,或者

"one,one, two;four$three two"作为三个令牌1. "one,one" 2. "two;four$three" 3. "two"

是否有任何一个可以将"one,one, two;four$three two"视为"one one two four three two",每个单独的令牌?

编写手动代码,如:

for(i=0;i<str.length();i++)
{
  //validating each character
}

当字符串非常长时,此操作将变得非常昂贵。

那么还有其他类似ispunct()的函数吗?还是其他什么?

在c中,我们这样做是为了比较每个字符:

  for(i=0;i<str.length();i++)
    {
      if(str[i]==',' || str[i]==",") // Is there any way here to compare with all puctuations in one shot?
        str[i]=" "; //replace with space
    }

在c++中,正确的方法是什么?

This operation will become very costly when string is very very long.

不,不会的。这将是一个O(n)操作,它对这个问题很好。这个操作再好不过了,因为无论如何,你都必须查看字符串中的每个字符。如果不查看字符串中的每个字符,就无法做到这一点。

假设您正在处理一个典型的8位字符集,我会从构建一个翻译表开始:

std::vector<char> trans(UCHAR_MAX);
for (int i=0; i<UCHAR_MAX; i++)
    trans[i] = ispunct(i) ? ' ' : i;

然后处理一个字符串的文本可以是这样的:

for (auto &ch : str)
    ch = trans[(unsigned char)ch];

对于8位字符集,转换表通常都适合您的一级缓存,并且循环只有一个高度可预测的分支(除非到达字符串末尾,否则总是执行),因此它应该相当快。

需要明确的是,当我说"相当快"时,我的意思是我的极不可能成为你所描述的过程中的瓶颈。你需要一个缓慢的处理器和快速的网络连接相结合,才能避免这成为处理网络数据的瓶颈。

如果你有一个10 GbE网络连接的树莓派,你可能需要做更多的优化工作才能跟上(但我不确定)。对于任何不那么严重的不匹配,网络显然将成为瓶颈。

So is there any other function like ispunct()? or anything else?

事实上,有。man ispunct给了我一个美丽的列表:

int isalnum(int c);
int isalpha(int c);
int isascii(int c);
int isblank(int c);
int iscntrl(int c);
int isdigit(int c);
int isgraph(int c);
int islower(int c);
int isprint(int c);
int ispunct(int c);
int isspace(int c);
int isupper(int c);
int isxdigit(int c);

你想拿什么就拿什么。

您也可以使用std::remove_copy_if来完全删除标点符号:

#include <algorithm>
#include <string>      
  string words = "I,love.punct-uation!";
  string result;  // this will be our final string after it has been purified
  // iterates through each character in the string
  // to remove all punctuation
  std::remove_copy_if(words.begin(), words.end(),            
                    std::back_inserter(result), //Store output           
                    std::ptr_fun<int, int>(&std::ispunct)  
                   );
  // ta-da!
  cout << result << endl;