如何用标准c++库替换字符串的一部分?

QString s("hello $name");  // Example using Qt.
s.replace("$name", "Somename");

当前回答

您可以使用此代码删除减法,也可以替换,也可以删除额外的空白。 代码:

#include<bits/stdc++.h>
using namespace std;

void removeSpaces(string &str)
{   
    int n = str.length();
    int i = 0, j = -1;

    bool spaceFound = false;
    while (++j <= n && str[j] == ' ');

    while (j <= n)
    {
        if (str[j] != ' ')
        {
          
            if ((str[j] == '.' || str[j] == ',' ||
                 str[j] == '?') && i - 1 >= 0 &&
                 str[i - 1] == ' ')
                str[i - 1] = str[j++];
            else str[i++] = str[j++];
 
            spaceFound = false;
        }
        else if (str[j++] == ' ')
        {
            if (!spaceFound)
            {
                str[i++] = ' ';
                spaceFound = true;
            }
        }
    }

    if (i <= 1)
         str.erase(str.begin() + i, str.end());
    else str.erase(str.begin() + i - 1, str.end());
}
int main()
{
    string s;
    cin >> s;

    for(int i = s.find("WUB"); i >= 0; i = s.find("WUB"))
        s.replace(i,3," ");
    removeSpaces(s);
    cout << s << endl;

    return 0;
}

其他回答

我自己的实现,考虑到字符串只需要调整一次大小,然后替换就可以发生。

template <typename T>
std::basic_string<T> replaceAll(const std::basic_string<T>& s, const T* from, const T* to)
{
    auto length = std::char_traits<T>::length;
    size_t toLen = length(to), fromLen = length(from), delta = toLen - fromLen;
    bool pass = false;
    std::string ns = s;

    size_t newLen = ns.length();

    for (bool estimate : { true, false })
    {
        size_t pos = 0;

        for (; (pos = ns.find(from, pos)) != std::string::npos; pos++)
        {
            if (estimate)
            {
                newLen += delta;
                pos += fromLen;
            }
            else
            {
                ns.replace(pos, fromLen, to);
                pos += delta;
            }
        }

        if (estimate)
            ns.resize(newLen);
    }

    return ns;
}

用法可以是这样的:

std::string dirSuite = replaceAll(replaceAll(relPath.parent_path().u8string(), "\\", "/"), ":", "");

如果你想快速完成,你可以使用两次扫描的方法。 伪代码:

首先解析。找出有多少匹配字符。 展开字符串的长度。 第二个解析。从字符串的末尾开始,当我们得到一个匹配,我们替换,否则我们只是复制字符从第一个字符串。

我不确定这是否可以优化到一个到位的算法。

和一个c++ 11代码示例,但我只搜索一个字符。

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

void ReplaceString(string& subject, char search, const string& replace)
{   
    size_t initSize = subject.size();
    int count = 0;
    for (auto c : subject) { 
        if (c == search) ++count;
    }

    size_t idx = subject.size()-1 + count * replace.size()-1;
    subject.resize(idx + 1, '\0');

    string reverseReplace{ replace };
    reverse(reverseReplace.begin(), reverseReplace.end());  

    char *end_ptr = &subject[initSize - 1];
    while (end_ptr >= &subject[0])
    {
        if (*end_ptr == search) {
            for (auto c : reverseReplace) {
                subject[idx - 1] = c;
                --idx;              
            }           
        }
        else {
            subject[idx - 1] = *end_ptr;
            --idx;
        }
        --end_ptr;
    }
}

int main()
{
    string s{ "Mr John Smith" };
    ReplaceString(s, ' ', "%20");
    cout << s << "\n";

}

使用std:: string::替换:

s.replace(s.find("$name"), sizeof("$name") - 1, "Somename");

在c++ 11中,你可以像这样使用std::regex:

#include <regex>
...
std::string string("hello $name");
string = std::regex_replace(string, std::regex("\\$name"), "Somename");

对于转义字符,需要使用双反斜杠。

您可以使用此代码删除减法,也可以替换,也可以删除额外的空白。 代码:

#include<bits/stdc++.h>
using namespace std;

void removeSpaces(string &str)
{   
    int n = str.length();
    int i = 0, j = -1;

    bool spaceFound = false;
    while (++j <= n && str[j] == ' ');

    while (j <= n)
    {
        if (str[j] != ' ')
        {
          
            if ((str[j] == '.' || str[j] == ',' ||
                 str[j] == '?') && i - 1 >= 0 &&
                 str[i - 1] == ' ')
                str[i - 1] = str[j++];
            else str[i++] = str[j++];
 
            spaceFound = false;
        }
        else if (str[j++] == ' ')
        {
            if (!spaceFound)
            {
                str[i++] = ' ';
                spaceFound = true;
            }
        }
    }

    if (i <= 1)
         str.erase(str.begin() + i, str.end());
    else str.erase(str.begin() + i - 1, str.end());
}
int main()
{
    string s;
    cin >> s;

    for(int i = s.find("WUB"); i >= 0; i = s.find("WUB"))
        s.replace(i,3," ");
    removeSpaces(s);
    cout << s << endl;

    return 0;
}