从字符串中删除特定的子字符串

Remove specific substring from string

本文关键字:字符串 删除      更新时间:2023-10-16

我想从消息中删除微笑符号。我已经用这个标签<sml/>定义了smiley,我绝对给了每个标签特定的数字。。像<sml1/><sml2/>,。。。,<sml30/>。它可以是特定字符串的子字符串,如:

这是消息<sml4/>

这里<sml4/>是消息。

<sml4/>这是消息。

我想从邮件中删除此标记。结果是:这是留言

std::string receivedMessage = msg.body();
    if (receivedMessage.find("<sml") != std::string::npos && receivedMessage.find("/>") != std::string::npos)
    {
       for(int i=0 ; i<=30 ; ++i)
        receivedMessage = receivedMessage.remove ("<sml".i."/>")
    }

有什么建议吗?

不使用正则表达式,例如,如果编译器不支持正则表达式,则可以执行演示程序中显示的任务

#include <iostream>
#include <string>
#include <cstring>
int main()
{
    for ( std::string s : { "Here is messages <sml4/>", "Here <sml4/> is messages", "<sml4/> Here is messages" } )
    {
        const char start[] = "<sml";
        const char end[]   = "/>";
        const size_t l = sizeof( end );
        std::string::size_type n1, n2;
        if ( ( n1 = s.find( start ) ) != std::string::npos && 
             ( n2 = s.find( end, n1 ) ) != std::string::npos ) 
        {
            n2 += l - 1;
            if ( n2 != s.size() && std::isblank( ( unsigned char )s[n2] ) ) ++n2;
            else if ( n1 != 0 && std::isblank( ( unsigned char )s[n1-1] ) ) --n1;
            std::cout << s << std::endl;
            s.erase( n1, n2 - n1 );                     
            std::cout << s << std::endl;
            std::cout << std::endl;
        }
    }                     
}

程序输出看起来像

Here is messages <sml4/>
Here is messages
Here <sml4/> is messages
Here is messages
<sml4/> Here is messages
Here is messages

同样为了简单起见,函数std::isblank的调用可以代替以下比较

            if ( n2 != s.size() && s[n2] == ' ' ) ++n2;
            else if ( n1 != 0 && s[n1-1] == ' ' ) --n1;

使用C++11,假设您有:

string message = R"Here is messages <sml4/>";

您可以编写一个简单的正则表达式(正如Amit在评论中所建议的那样(。把它放在代码中:

string messageWithoutSmiles = regex_replace(message,
    regex(R"<s*smld+s*/s*>"), "");

Regex非常简单,但一点解释可能会有所帮助:

  • CCD_ 9<字符后面跟零个或多个空格
  • sml文字字符串
  • CCD_ 11后跟一个或多个数字(相当于[0-9](
  • CCD_ 13后面跟着零个或多个空白
  • /s*/字符后面有零个或多个空白
  • >关闭>

如果C++11不是一个选项(!(,并且您已经在使用boost,那么您就有了一个等效的regex工具。只是为了好玩你也可以手动实现类似的东西(没有空白来简化代码,远离性能POV,为了处理空白,只需在原子单元中添加更多的.find()分裂令牌<sml>、/>和

while (true) {
    const string::size_type n1 = message.find("<sml", 0);
    if (n1 == string::npos)
       break;
    const string::size_type n2 = message.find("/>", n1);
    if (n2 == string::npos)
       break;
    message = message.erase(n1, n2 - n1 + 2);
}

注意:代码不是最佳,甚至也不是nice(它应该封装在一个函数中,在现实生活中你不会使用while (true)(,但它的目的是说明性的(然后易于阅读和理解(,而不是准备好使用。

std::string message = "Here is messages < sml4/> ";             
std::size_t found =  message.find("< sml4/> ");
if (found!=std::string::npos)
{                                                     
 message.erase(found,found+sizeof("< sml4/> ")); 
}