#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. Готово, извините за беспокойство