Как я могу заменить все слова в строке, кроме одного

#c

#c

Вопрос:

Итак, я хотел бы изменить все слова в строке, кроме одного, которое остается посередине.

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

Ожидалось, что результат будет:

 This is a test about player group
  

Но это не работает, вывод:

 You want to join player group
  

Проблема заключается в поиске слов, поскольку они являются уникальной строкой.
Есть функция, которая считывает все слова, независимо от их положения, и просто меняет то, что я хочу?

РЕДАКТИРОВАНИЕ 2: это лучший пример того, что я хочу, чтобы произошло:

     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
  

Комментарии:

1. Где вы пытаетесь? Похоже на задачу hackerrank 😉 . Разделить на ‘ ‘ пустую строку для по символу. Затем просто найдите mid (сумма слов / 2). В конце проверьте left и right size(), если у вас нечетная сумма.

2. Вы также намеревались перейти master на leader ?

3. Да, еще раз извините за мое плохое объяснение, редактирование было обновлено

4. Знаете ли вы заранее, где слово, которое вы хотите сохранить, будет находиться в строке replace (или c )?

5. Нет, слово не подлежит замене, но что вы предлагаете?

Ответ №1:

Здесь вам нужно изменить свое мышление. Вместо сопоставления «всех слов, кроме одного», вам нужно попытаться сопоставить это одно слово, чтобы вы могли извлечь его и вставить в другое место.

Мы можем сделать это с помощью регулярных выражений, которые стали стандартизированными в 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_resu<
if (!std::regex_search(test, search_result, find))
{
    std::cerr << "Could not match the stringn";
    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;
}
  

Живая демонстрация

Чтобы сопоставить слово «player», я использовал довольно простое регулярное выражение (S ) , которое означает «сопоставьте один или несколько непробельных символов (жадно) и поместите их в группу»

«Группы» в регулярных выражениях заключаются в круглые скобки. 0-я группа — это всегда полное совпадение, и поскольку у нас есть только один набор круглых скобок, ваше слово, следовательно, находится в группе 1, следовательно, результирующий доступ к результату совпадения at search_result[1] .

Для создания регулярного выражения вы заметите, что я использовал, возможно, незнакомый синтаксис строкового литерала R"(...)" . Это называется необработанным строковым литералом и также было стандартизировано в C 11. В основном это было сделано для описания регулярных выражений без необходимости экранирования обратной косой черты. Если вы использовали Python, это то же самое, что r'...' . Если вы использовали C #, это то же самое, что @"..."

Я добавил некоторые boost::format , чтобы распечатать результат, потому что вы использовали Boost в вопросе, и я подумал, что вы хотели бы повеселиться с этим 🙂

Комментарии:

1. Спасибо, это то, что я хотел! Но у меня есть небольшой вопрос, как я могу поместить строку (например: test) внутри std::regex find этого выражения (S ) ?

2. @Nathan: Вы спрашиваете, как это сделать?

3. Нет, вероятно, лучше использовать реальный пример. У меня есть программа, которая обрабатывает это (например): "The player %s is now master", "AndyG"" и выводит это: The player AndyG is now master итак, я хочу сохранить ваше имя, преобразовав строку в The player AndyG is now leader

4. @Nathan: Кажется, я начинаю понимать. Простите меня, если я все еще немного не в себе. Похоже, что использование boost::format — это то, что вы хотите. boost::format("The player %1% is now master") % "AndyG"

5. Не нужно извиняться, вы очень помогли, спасибо за время! Да, но я хочу что-то вроде этого: « std::string test = «Вы хотите присоединиться к группе игроков»; static const std::regex find{R»(S )» test }; « но просто вызываю игрока, ничего больше

Ответ №2:

В вашем примере find не является подстрокой test , поэтому boost::replace_all(test, find, replace); не имеет никакого эффекта.

Удаление group из find и replace решает его:

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

Вывод: This is a test about player group .

В этом случае выполняется только одна замена начала строки, потому что конец строки уже является правильным. У вас может быть другой вызов replace_all , чтобы изменить конец, если это необходимо.

Некоторые другие варианты:

  • один находится в другом ответе.
  • разделите строки на вектор (или массив) слов, затем вставьте нужное слово (player) в нужное место вектора замены, затем создайте из него свою выходную строку.

Комментарии:

1. Да, но я не хочу удалять группу слов, она должна быть там.

2. @Nathan Это должно быть где? Если в выходных данных, это так.

3. Это всего лишь пример большой программы, которая работает с подобным образом: "The player %s is the master now!", "Keldorn" и я хочу перевести ее на другие языки, и я не могу сделать это так, как вы говорите

4. Этот ответ выполняет то, что задано в вопросе. Если это другие ограничения, пожалуйста, добавьте их в вопрос.

5. Готово, извините за беспокойство