如何查找和替换字符串?

时间:2021-11-17 18:29:15

If s is a std::string, then is there a function like the following?

如果s是std::string,那么是否有如下的函数?

s.replace("text to replace", "new text");

8 个解决方案

#1


72  

Try a combination of std::string::find and std::string::replace.

尝试结合std::查找和std::string::replace。

This gets the position:

这得到了位置:

size_t f = s.find("text to replace");

And this replaces the first occurrence:

这代替了第一个事件:

s.replace(f, std::string("text to replace").length(), "new text");

Now you can simply create a function for your convenience:

现在您可以简单地为您的方便创建一个函数:

std::string replaceFirstOccurrence(std::string& s,
    const std::string& toReplace,
    const std::string& replaceWith)
{
    std::size_t pos = s.find(toReplace);
    if (pos == std::string::npos) return s;
    return s.replace(pos, toReplace.length(), replaceWith);
}

#2


23  

Yes: replace_all is one of the boost string algorithms:

是的:replace_all是boost字符串算法中的一个:

Although it's not a standard library, it has a few things on the standard library:

虽然它不是标准的库,但是它在标准库中有一些东西:

  1. More natural notation based on ranges rather than iterator pairs. This is nice because you can nest string manipulations (e.g., replace_all nested inside a trim). That's a bit more involved for the standard library functions.
  2. 基于范围而不是迭代器对的更自然的符号。这很好,因为您可以嵌套字符串操作(例如,replace_all嵌套在一个trim中)。这对于标准库函数来说有点复杂。
  3. Completeness. This isn't hard to be 'better' at; the standard library is fairly spartan. For example, the boost string algorithms give you explicit control over how string manipulations are performed (i.e., in place or through a copy).
  4. 完整性。这并不难做到“更好”;标准的图书馆相当简朴。例如,boost字符串算法使您可以显式地控制如何执行字符串操作(即:,在适当的地方或通过一份副本。

#3


20  

Do we really need a Boost library for seemingly such a simple task?

我们真的需要一个Boost库来完成看似简单的任务吗?

To replace all occurences of a substring use this function:

要替换一个子字符串的所有发生,使用这个函数:

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

If you need performance, here is an optimized function that modifies the input string, it does not create a copy of the string:

如果您需要性能,这里是一个优化的函数,它修改输入字符串,它不会创建字符串的副本:

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

Tests:

测试:

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;

Output:

输出:

Input string: abc abc def
ReplaceString() return value: a!! a!! def
ReplaceString() input string not modified: abc abc def
ReplaceStringInPlace() input string modified: a?? a?? def

#4


9  

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

int main ()
{
    string str("one three two four");
    string str2("three");
    str.replace(str.find(str2),str2.length(),"five");
    cout << str << endl;
    return 0;
}

Output

one five two four

#5


7  

like some say boost::replace_all

像有人说提高::replace_all

here a dummy example:

在一个虚拟的例子:

    #include <boost/algorithm/string/replace.hpp>

    std::string path("file.gz");
    boost::replace_all(path, ".gz", ".zip");

#6


2  

Not exactly that, but std::string has many replace overloaded functions.

不是那样的,但是std::string有很多替换重载的函数。

Go through this link to see explanation of each, with examples as to how they're used.

通过这个链接查看每一个的解释,并举例说明它们是如何使用的。

Also, there are several versions of string::find functions (listed below) which you can use in conjunction with string::replace.

此外,还有几个版本的string::find函数(下面列出),可以与string一起使用::replace。

  • find
  • 找到
  • rfind
  • rfind
  • find_first_of
  • find_first_of
  • find_last_of
  • find_last_of
  • find_first_not_of
  • find_first_not_of
  • find_last_not_of
  • find_last_not_of

Also, note that there are several versions of replace functions available from <algorithm> which you can also use (instead of string::replace):

另外,请注意,有几个版本的替换函数可以从 <算法> 中获得,您也可以使用它(而不是string::replace):

  • replace
  • 取代
  • replace_if
  • replace_if
  • replace_copy
  • replace_copy
  • replace_copy_if
  • replace_copy_if

#7


2  

// replaced text will be in buffer.
void Replace(char* buffer, const char* source, const char* oldStr,  const char* newStr)
{
    if(buffer==NULL || source == NULL || oldStr == NULL || newStr == NULL) return; 

    int slen = strlen(source);
    int olen = strlen(oldStr);
    int nlen = strlen(newStr);

    if(olen>slen) return;
    int ix=0;

    for(int i=0;i<slen;i++)
    {
        if(oldStr[0] == source[i])
        {
            bool found = true;
            for(int j=1;j<olen;j++)
            {
                if(source[i+j]!=oldStr[j])
                {
                    found = false;
                    break;
                }
            }

            if(found)
            {
                for(int j=0;j<nlen;j++)
                    buffer[ix++] = newStr[j];

                i+=(olen-1);
            }
            else
            {
                buffer[ix++] = source[i];
            }
        }
        else
        {
            buffer[ix++] = source[i];
        }
    }
}

#8


0  

Here's the version I ended up writing that replaces all instances of the target string in a given string. Works on any string type.

这是我最后编写的版本,它用给定的字符串替换目标字符串的所有实例。适用于任何字符串类型。

template <typename T, typename U>
T &replace (
          T &str, 
    const U &from, 
    const U &to)
{
    size_t pos;
    size_t offset = 0;
    const size_t increment = to.size();

    while ((pos = str.find(from, offset)) != T::npos)
    {
        str.replace(pos, from.size(), to);
        offset = pos + increment;
    }

    return str;
}

Example:

例子:

auto foo = "this is a test"s;
replace(foo, "is"s, "wis"s);
cout << foo;

Output:

输出:

thwis wis a test

Note that even if the search string appears in the replacement string, this works correctly.

请注意,即使搜索字符串出现在替换字符串中,也可以正常工作。

#1


72  

Try a combination of std::string::find and std::string::replace.

尝试结合std::查找和std::string::replace。

This gets the position:

这得到了位置:

size_t f = s.find("text to replace");

And this replaces the first occurrence:

这代替了第一个事件:

s.replace(f, std::string("text to replace").length(), "new text");

Now you can simply create a function for your convenience:

现在您可以简单地为您的方便创建一个函数:

std::string replaceFirstOccurrence(std::string& s,
    const std::string& toReplace,
    const std::string& replaceWith)
{
    std::size_t pos = s.find(toReplace);
    if (pos == std::string::npos) return s;
    return s.replace(pos, toReplace.length(), replaceWith);
}

#2


23  

Yes: replace_all is one of the boost string algorithms:

是的:replace_all是boost字符串算法中的一个:

Although it's not a standard library, it has a few things on the standard library:

虽然它不是标准的库,但是它在标准库中有一些东西:

  1. More natural notation based on ranges rather than iterator pairs. This is nice because you can nest string manipulations (e.g., replace_all nested inside a trim). That's a bit more involved for the standard library functions.
  2. 基于范围而不是迭代器对的更自然的符号。这很好,因为您可以嵌套字符串操作(例如,replace_all嵌套在一个trim中)。这对于标准库函数来说有点复杂。
  3. Completeness. This isn't hard to be 'better' at; the standard library is fairly spartan. For example, the boost string algorithms give you explicit control over how string manipulations are performed (i.e., in place or through a copy).
  4. 完整性。这并不难做到“更好”;标准的图书馆相当简朴。例如,boost字符串算法使您可以显式地控制如何执行字符串操作(即:,在适当的地方或通过一份副本。

#3


20  

Do we really need a Boost library for seemingly such a simple task?

我们真的需要一个Boost库来完成看似简单的任务吗?

To replace all occurences of a substring use this function:

要替换一个子字符串的所有发生,使用这个函数:

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

If you need performance, here is an optimized function that modifies the input string, it does not create a copy of the string:

如果您需要性能,这里是一个优化的函数,它修改输入字符串,它不会创建字符串的副本:

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

Tests:

测试:

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;

Output:

输出:

Input string: abc abc def
ReplaceString() return value: a!! a!! def
ReplaceString() input string not modified: abc abc def
ReplaceStringInPlace() input string modified: a?? a?? def

#4


9  

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

int main ()
{
    string str("one three two four");
    string str2("three");
    str.replace(str.find(str2),str2.length(),"five");
    cout << str << endl;
    return 0;
}

Output

one five two four

#5


7  

like some say boost::replace_all

像有人说提高::replace_all

here a dummy example:

在一个虚拟的例子:

    #include <boost/algorithm/string/replace.hpp>

    std::string path("file.gz");
    boost::replace_all(path, ".gz", ".zip");

#6


2  

Not exactly that, but std::string has many replace overloaded functions.

不是那样的,但是std::string有很多替换重载的函数。

Go through this link to see explanation of each, with examples as to how they're used.

通过这个链接查看每一个的解释,并举例说明它们是如何使用的。

Also, there are several versions of string::find functions (listed below) which you can use in conjunction with string::replace.

此外,还有几个版本的string::find函数(下面列出),可以与string一起使用::replace。

  • find
  • 找到
  • rfind
  • rfind
  • find_first_of
  • find_first_of
  • find_last_of
  • find_last_of
  • find_first_not_of
  • find_first_not_of
  • find_last_not_of
  • find_last_not_of

Also, note that there are several versions of replace functions available from <algorithm> which you can also use (instead of string::replace):

另外,请注意,有几个版本的替换函数可以从 <算法> 中获得,您也可以使用它(而不是string::replace):

  • replace
  • 取代
  • replace_if
  • replace_if
  • replace_copy
  • replace_copy
  • replace_copy_if
  • replace_copy_if

#7


2  

// replaced text will be in buffer.
void Replace(char* buffer, const char* source, const char* oldStr,  const char* newStr)
{
    if(buffer==NULL || source == NULL || oldStr == NULL || newStr == NULL) return; 

    int slen = strlen(source);
    int olen = strlen(oldStr);
    int nlen = strlen(newStr);

    if(olen>slen) return;
    int ix=0;

    for(int i=0;i<slen;i++)
    {
        if(oldStr[0] == source[i])
        {
            bool found = true;
            for(int j=1;j<olen;j++)
            {
                if(source[i+j]!=oldStr[j])
                {
                    found = false;
                    break;
                }
            }

            if(found)
            {
                for(int j=0;j<nlen;j++)
                    buffer[ix++] = newStr[j];

                i+=(olen-1);
            }
            else
            {
                buffer[ix++] = source[i];
            }
        }
        else
        {
            buffer[ix++] = source[i];
        }
    }
}

#8


0  

Here's the version I ended up writing that replaces all instances of the target string in a given string. Works on any string type.

这是我最后编写的版本,它用给定的字符串替换目标字符串的所有实例。适用于任何字符串类型。

template <typename T, typename U>
T &replace (
          T &str, 
    const U &from, 
    const U &to)
{
    size_t pos;
    size_t offset = 0;
    const size_t increment = to.size();

    while ((pos = str.find(from, offset)) != T::npos)
    {
        str.replace(pos, from.size(), to);
        offset = pos + increment;
    }

    return str;
}

Example:

例子:

auto foo = "this is a test"s;
replace(foo, "is"s, "wis"s);
cout << foo;

Output:

输出:

thwis wis a test

Note that even if the search string appears in the replacement string, this works correctly.

请注意,即使搜索字符串出现在替换字符串中,也可以正常工作。