Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用另一个字符串替换字符串的一部分 在C++中,用另一个字符串替换字符串的一部分是可能的吗?_C++_String_Replace_Substring_Std - Fatal编程技术网

用另一个字符串替换字符串的一部分 在C++中,用另一个字符串替换字符串的一部分是可能的吗?

用另一个字符串替换字符串的一部分 在C++中,用另一个字符串替换字符串的一部分是可能的吗?,c++,string,replace,substring,std,C++,String,Replace,Substring,Std,基本上,我想这样做: QString string("hello $name"); string.replace("$name", "Somename"); >但我想使用标准C++库。 STD::String 有一个方法,那就是你要找的吗?< /P> 你可以试试: s.replace(s.find("$name"), sizeof("$name") - 1, "Somename"); 我自己没有试过,只是阅读了find()和replace()的文档,是的,您可以这样做,但是您必须用字符串

基本上,我想这样做:

QString string("hello $name");
string.replace("$name", "Somename");

<> >但我想使用标准C++库。

<代码> STD::String 有一个方法,那就是你要找的吗?< /P> 你可以试试:

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

我自己没有试过,只是阅读了
find()
replace()
的文档,是的,您可以这样做,但是您必须用字符串的find()成员找到第一个字符串的位置,然后用它的replace()成员替换


如果您打算使用标准库,您应该真正拥有一本涵盖所有这些内容的书。

有一个函数可以在字符串()中查找子字符串,还有一个函数可以用另一个字符串()替换字符串中的特定范围,因此您可以将它们组合起来以获得想要的效果:

bool replace(std::string& str, const std::string& from, const std::string& to) {
    size_t start_pos = str.find(from);
    if(start_pos == std::string::npos)
        return false;
    str.replace(start_pos, from.length(), to);
    return true;
}

std::string string("hello $name");
replace(string, "$name", "Somename");

作为对一条评论的回应,我认为
replaceAll
可能看起来像这样:

void replaceAll(std::string& str, const std::string& from, const std::string& to) {
    if(from.empty())
        return;
    size_t start_pos = 0;
    while((start_pos = str.find(from, start_pos)) != std::string::npos) {
        str.replace(start_pos, from.length(), to);
        start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
    }
}
std::string dirSuite = replaceAll(replaceAll(relPath.parent_path().u8string(), "\\", "/"), ":", "");

要返回新字符串,请使用以下命令:

std::string ReplaceString(std::string subject, const std::string& search,
                          const std::string& replace) {
    size_t pos = 0;
    while ((pos = subject.find(search, pos)) != std::string::npos) {
         subject.replace(pos, search.length(), replace);
         pos += replace.length();
    }
    return subject;
}
如果需要性能,这里有一个修改输入字符串的优化函数,它不会创建字符串的副本:

void ReplaceStringInPlace(std::string& subject, const std::string& search,
                          const std::string& replace) {
    size_t pos = 0;
    while ((pos = subject.find(search, pos)) != std::string::npos) {
         subject.replace(pos, search.length(), replace);
         pos += replace.length();
    }
}
测试:

std::string input = "abc abc def";
std::cout << "Input string: " << input << std::endl;

std::cout << "ReplaceString() return value: " 
          << ReplaceString(input, "bc", "!!") << std::endl;
std::cout << "ReplaceString() input string not modified: " 
          << input << std::endl;

ReplaceStringInPlace(input, "bc", "??");
std::cout << "ReplaceStringInPlace() input string modified: " 
          << input << std::endl;
我通常使用:

std::string& replace(std::string& s, const std::string& from, const std::string& to)
{
    if(!from.empty())
        for(size_t pos = 0; (pos = s.find(from, pos)) != std::string::npos; pos += to.size())
            s.replace(pos, from.size(), to);
    return s;
}

它反复调用
std::string::find()
,以查找搜索字符串的其他匹配项,直到
std::string::find()
没有找到任何内容为止。因为
std::string::find()
返回匹配的位置,所以我们没有使迭代器无效的问题。

对于C++11,您可以像这样使用
std::regex

#include <regex>
...
std::string string("hello $name");
string = std::regex_replace(string, std::regex("\\$name"), "Somename");
#包括
...
std::string字符串(“hello$name”);
string=std::regex\u replace(string,std::regex(“\\$name”),“Somename”);

转义转义字符需要双反斜杠。

这听起来像是一个选项

string.replace(string.find(“%s”)、string(“%s”).size()、“Something”)

您可以将其封装在函数中,但这一行解决方案听起来可以接受。
问题是,这只会改变第一次出现,你可能想循环它,但是它也允许你用相同的符号(这个字符串中插入几个变量):(代码>%s)

我现在正在学习C++,但是编辑以前发布的一些代码,我可能会使用这样的东西。这使您可以灵活地替换1个或多个实例,还可以指定起点

using namespace std;

// returns number of replacements made in string
long strReplace(string& str, const string& from, const string& to, size_t start = 0, long count = -1) {
    if (from.empty()) return 0;

    size_t startpos = str.find(from, start);
    long replaceCount = 0;

    while (startpos != string::npos){
        str.replace(startpos, from.length(), to);
        startpos += to.length();
        replaceCount++;

        if (count > 0 && replaceCount >= count) break;
        startpos = str.find(from, startpos);
    }

    return replaceCount;
}

如果所有字符串都是STD::String,如果使用<代码> siZOFF()/CUT>,字符的截断会出现奇怪的问题,因为它是针对C字符串而不是C++字符串的。修复方法是使用

std::string
.size()
类方法

sHaystack.replace(sHaystack.find(sNeedle), sNeedle.size(), sReplace);
这将替换sHaystack内联——无需再对其执行=赋值

用法示例:

std::string sHaystack = "This is %XXX% test.";
std::string sNeedle = "%XXX%";
std::string sReplace = "my special";
sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
std::cout << sHaystack << std::endl;
std::string sHaystack=“这是%XXX%测试。”;
std::string sNeedle=“%XXX%”;
std::string sReplace=“我的特别”;
替换(sHaystack.find(sNeedle),sNeedle.size(),sReplace);

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

  • 首先解析。找到匹配的字符数
  • 展开字符串的长度
  • 第二个解析。当我们得到替换的匹配项时,从字符串的末尾开始,否则我们只复制第一个字符串中的字符
  • 我不确定这是否可以优化到一个就地算法

    和一个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;
    void ReplaceString(字符串和主题、字符搜索、常量字符串和替换)
    {   
    size_t initSize=subject.size();
    整数计数=0;
    对于(自动c:主题){
    如果(c==搜索)+计数;
    }
    size\u t idx=subject.size()-1+count*replace.size()-1;
    subject.resize(idx+1,“\0”);
    字符串反向替换{replace};
    反向(reverseReplace.begin(),reverseReplace.end());
    char*end_ptr=&subject[initSize-1];
    while(end_ptr>=&主题[0])
    {
    如果(*end_ptr==搜索){
    用于(自动c:反向替换){
    受试者[idx-1]=c;
    --idx;
    }           
    }
    否则{
    受试者[idx-1]=*结束ptr;
    --idx;
    }
    --结束ptr;
    }
    }
    int main()
    {
    字符串s{“John Smith先生”};
    替换字符串,,“%20”);
    
    cout我自己的实现,考虑到字符串只需要调整一次大小,然后就可以进行替换

    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;
    }
    

    这可能是更好的使用

    void replace(string& input, const string& from, const string& to)
    {
        while(true)
        {
            size_t startPosition = input.find(from);
            if(startPosition == string::npos)
                break;
            input.replace(startPosition, from.length(), to);
        }
    }
    

    您可以使用此代码删除子字符串,也可以替换,还可以删除额外的空白。 代码:

    #包括
    使用名称空间std;
    void removespace(字符串和字符串)
    {
    int n=str.length();
    int i=0,j=-1;
    bool spaceFound=false;
    而(++js;
    对于(int i=s.find(“WUB”);i>=0;i=s.find(“WUB”))
    {
    s、 替换(i,3,“”);
    }
    移除空间;
    
    从我看到的情况来看,std::string replace方法没有像我希望的那样接受两个字符串。这对我不起作用。sizeof应该被string(“Somename”).size()替换-1@TimZaman:这让我很困惑,文档清楚地说明可以从C样式字符串初始化。第二个参数的长度应为“$name”(而不是“Somename”的长度),不是吗?如果有多个
    “$name”出现,这将不起作用<代码> >代码> S>。代码可能是AcOs,抱歉,是C,不是C++;我希望我可以投票。@ Pyl I认为这也必须被问到C++,但是我不能发现它有STD标签,但是也许你可能对Boost的字符串算法感兴趣,它也包含了广泛的替换算法的选择。(in place/copy,区分大小写/不区分大小写,替换第一个/最后一个/所有/n-th)。@Michael Mrozek在上有一个,但它更新了,并且这里的替换所有方法更健壮。可能是duplica
    
    #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";
    
    }
    
    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(), "\\", "/"), ":", "");
    
    void replace(string& input, const string& from, const string& to)
    {
        while(true)
        {
            size_t startPosition = input.find(from);
            if(startPosition == string::npos)
                break;
            input.replace(startPosition, from.length(), to);
        }
    }
    
    #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;
    }