简体   繁体   中英

How can I replace all words in a string except one

So, I would like to change all words in a string except one, that stays in the middle.

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

int main()
{
    string test = "You want to join player group";
    string find = "You want to join group";
    string replace = "This is a test about group";

    boost::replace_all(test, find, replace);

    cout << test << endl;
}

The output was expected to be:

This is a test about player group

But it doesn't work, the output is:

You want to join player group

The problem is on finding out the words, since they are a unique string. There's a function that reads all words, no matter their position and just change what I want?

EDIT2: This is the best example of what I want to happen:

    char* a  = "This is MYYYYYYYYY line in the void Translate"; // This is the main line
    char* b = "This is line in the void Translate"; // This is what needs to be find in the main line
    char* c = "Testing - is line twatawtn thdwae voiwd Transwlate"; // This needs to replace ALL the words in the char* b, perserving the MYYYYYYYYY

    // The output is expected to be:
    Testing - is MYYYYYYYY is line twatawtn thdwae voiwd Transwlate

You need to invert your thinking here. Instead of matching "All words but one", you need to try to match that one word so you can extract it and insert it elsewhere.

We can do this with Regular Expressions , which became standardized in C++11:

std::string test = "You want to join player group";
static const std::regex find{R"(You want to join (\S+) group)"};
std::smatch search_result;
if (!std::regex_search(test, search_result, find))
{
    std::cerr << "Could not match the string\n";
    exit(1);
}
else
{
    std::string found_group_name = search_result[1];
    auto replace = boost::format("This is a test about %1% group") % found_group_name;
    std::cout << replace;
}

Live Demo

To match the word "player" I used a pretty simply regular expression (\\S+) which means "match one or more non-whitespace characters (greedily) and put that into a group"

"Groups" in regular expressions are enclosed by parentheses. The 0th group is always the entire match, and since we only have one set of parentheses, your word is therefore in group 1, hence the resulting access of the match result at search_result[1] .

To create the regular expression, you'll notice I used the perhaps-unfamiliar string literal syntax R"(...)" . This is called a raw string literal and was also standardized in C++11. It was basically made for describing regular expressions without needing to escape backslashes. If you've used Python, it's the same as r'...' . If you've used C#, it's the same as @"..."

I threw in some boost::format to print the result because you were using Boost in the question and I thought you'd like to have some fun with it :-)

In your example, find is not a substring of test , so boost::replace_all(test, find, replace); has no effect.

Removing group from find and replace solves it:

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

int main()
{
  std::string test = "You want to join player group";
  std::string find = "You want to join";
  std::string replace = "This is a test about";

  boost::replace_all(test, find, replace);

  std::cout << test << std::endl;
}

Output: This is a test about player group .

In this case, there is just one replace of the beginning of the string because the end of the string is already the right one. You could have another call of replace_all to change the end if needed.

Some other options:

  • one is in the other answer.
  • split the strings into a vector (or array) of words, then insert the desired word (player) at the right spot of the replace vector, then build your output string from it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM