C++ 从字符串中删除标点符号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19138983/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:32:38  来源:igfitidea点击:

C++ Remove punctuation from String

c++stringparsingerasepunctuation

提问by NewFile

I got a string and I want to remove all the punctuations from it. How do I do that? I did some research and found that people use the ispunct() function (I tried that), but I cant seem to get it to work in my code. Anyone got any ideas?

我有一个字符串,我想从中删除所有标点符号。我怎么做?我做了一些研究,发现人们使用 ispunct() 函数(我试过了),但我似乎无法让它在我的代码中工作。有人有任何想法吗?

#include <string>

int main() {

string text = "this. is my string. it's here."

if (ispunct(text))
text.erase();

return 0;
}

采纳答案by NewFile

i got it.

我知道了。

size_t found = text.find('.');
text.erase(found, 1);

回答by P0W

Using algorithm remove_copy_if:-

使用算法remove_copy_if:-

string text,result;
std::remove_copy_if(text.begin(), text.end(),            
                        std::back_inserter(result), //Store output           
                        std::ptr_fun<int, int>(&std::ispunct)  
                       );

回答by Steve314

POW already has a good answer if you need the result as a new string. This answer is how to handle it if you want an in-place update.

如果您需要将结果作为新字符串,POW 已经有了很好的答案。如果您想要就地更新,此答案是如何处理它。

The first part of the recipe is std::remove_if, which can remove the punctuation efficiently, packing all the non-punctuation as it goes.

配方的第一部分是std::remove_if,它可以有效地去除标点符号,将所有非标点符号打包。

std::remove_if (text.begin (), text.end (), ispunct)

Unfortunately, std::remove_ifdoesn't shrink the string to the new size. It can't because it has no access to the container itself. Therefore, there's junk characters left in the string after the packed result.

不幸的是,std::remove_if不会将字符串缩小到新的大小。它不能,因为它无法访问容器本身。因此,在打包结果之后,字符串中还剩下垃圾字符。

To handle this, std::remove_ifreturns an iterator that indicates the part of the string that's still needed. This can be used with strings erasemethod, leading to the following idiom...

为了处理这个问题,std::remove_if返回一个迭代器,指示仍然需要的字符串部分。这可以与字符串erase方法一起使用,导致以下习语...

text.erase (std::remove_if (text.begin (), text.end (), ispunct), text.end ());

I call this an idiom because it's a common technique that works in many situations. Other types than stringprovide suitable erasemethods, and std::remove(and probably some other algorithm library functions I've forgotten for the moment) take this approach of closing the gaps for items they remove, but leaving the container-resizing to the caller.

我称其为习语,因为它是一种适用于许多情况的常用技术。除了string提供合适的erase方法之外的其他类型,以及std::remove(可能还有一些我暂时忘记的其他算法库函数)采用这种方法来关闭它们删除的项目的间隙,但将容器调整大小留给调用者。

回答by CS Pei

ispuncttakes a charvalue not a string.

ispunct接受一个char值而不是一个字符串。

you can do like

你可以喜欢

for (auto c : string)
     if (ispunct(c)) text.erase(text.find_first_of(c));

This will work but it is a slow algorithm.

这会起作用,但它是一种缓慢的算法。

回答by thefourtheye

#include <string>
#include <iostream>
#include <cctype>

int main() {

    std::string text = "this. is my string. it's here.";

    for (int i = 0, len = text.size(); i < len; i++)
    {
        if (ispunct(text[i]))
        {
            text.erase(i--, 1);
            len = text.size();
        }
    }

    std::cout << text;
    return 0;
}

Output

输出

this is my string its here

When you delete a character, the size of the string changes. It has to be updated whenever deletion occurs. And, you deleted the current character, so the next character becomes the current character. If you don't decrement the loop counter, the character next to the punctuation character will not be checked.

删除字符时,字符串的大小会发生变化。每当发生删除时都必须更新它。并且,您删除了当前字符,因此下一个字符成为当前字符。如果不减少循环计数器,则不会检查标点字符旁边的字符。

回答by user1233963

#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

int main() {
    string str = "this. is my string. it's here.";

    transform(str.begin(), str.end(), str.begin(), [](char ch)
    {
        if( ispunct(ch) )
            return '
text.erase (std::remove_if (text.begin (), text.end (), ::ispunct), text.end ());
'; return ch; }); }

回答by Siddharth Singh

Pretty good answer by Steve314. I would like to add a small change :

Steve314 的回答非常好。我想添加一个小改动:

for(size_t i = 0; i<text.length(); ++i)
  if(ispunct(text[i]))
    text.erase(i--, 1);

Adding the :: before the function ispunct takes care of overloading .

在函数 ispunct 之前添加 :: 负责重载。

回答by pippin1289

The problem here is that ispunct() takes one argument being a character, while you are trying to send a string. You should loop over the elements of the string and erase each character if it is a punctuation like here:

这里的问题是 ispunct() 将一个参数作为一个字符,而您正在尝试发送一个字符串。您应该遍历字符串的元素并删除每个字符,如果它是像这里这样的标点符号:

 #include <iostream>
 #include <string>

 using namespace std;

 int main()
 {
   string s;//string is defined here.

  cout << "Please enter a string with punctuation's: " << endl;//Asking for users input

  getline(cin, s);//reads in a single string one line at a time

/* ERROR Check: The loop didn't run at first because a semi-colon was placed at the end 
                of the statement.  Remember not to add it for loops. */
        for(auto &c : s)  //loop checks every character 
        {       
             if (ispunct(c)) //to see if its a punctuation
              {
               c=' ';       //if so it replaces it with a blank space.(delete) 
              }

        }

        cout <<  s << endl; 


   system("pause");
   return 0;
   }

回答by prsmith

#include <ctype.h> //needed for ispunct()
string onlyLetters(string str){
    string retStr = "";

    for(int i = 0; i < str.length(); i++){
        if(!ispunct(str[i])){
            retStr += str[i];
        }
    }
    return retStr;

回答by willard5991

Another way you could do this would be as follows:

您可以执行此操作的另一种方法如下:

##代码##

This ends up creating a new string instead of actually erasing the characters from the old string, but it is a little easier to wrap your head around than using some of the more complex built in functions.

这最终会创建一个新字符串,而不是实际删除旧字符串中的字符,但与使用一些更复杂的内置函数相比,绕起来要容易一些。

回答by Loshiye Sindiyo

Try to use this one, it will remove all the punctuation on the string in the text file oky. str.erase(remove_if(str.begin(), str.end(), ::ispunct), str.end());

尝试使用这个,它会删除文本文件中字符串上的所有标点符号 ok。str.erase(remove_if(str.begin(), str.end(), ::ispunct), str.end());

please reply if helpful

如果有帮助请回复