Có cách nào để thay thế tất cả các lần xuất hiện của một chuỗi con bằng một chuỗi khác trong std::string
không?
Ví dụ:
void SomeFunction(std::string& str)
{
str = str.replace("hello", "world"); //< I'm looking for something nice like this
}
Có cách nào để thay thế tất cả các lần xuất hiện của một chuỗi con bằng một chuỗi khác trong std::string
không?
Ví dụ:
void SomeFunction(std::string& str)
{
str = str.replace("hello", "world"); //< I'm looking for something nice like this
}
Câu trả lời:
Tại sao không thực hiện thay thế của riêng bạn?
void myReplace(std::string& str,
const std::string& oldStr,
const std::string& newStr)
{
std::string::size_type pos = 0u;
while((pos = str.find(oldStr, pos)) != std::string::npos){
str.replace(pos, oldStr.length(), newStr);
pos += newStr.length();
}
}
#include <boost/algorithm/string.hpp> // include Boost, a C++ library
...
std::string target("Would you like a foo of chocolate. Two foos of chocolate?");
boost::replace_all(target, "foo", "bar");
Đây là tài liệu chính thức về Replace_all.
replace_all
sẽ segfault cho các phiên bản của tăng> 1,43 trên Sun Studio cho bất kỳ phiên bản <12,3
boost
tăng đáng kể thời gian biên dịch trên các thiết bị nhúng. Ngay cả lõi tứ ARMv7. 100 dòng mã biên dịch trong 2 phút, không cần tăng tốc, 2 giây.
Trong C ++ 11, bạn có thể thực hiện việc này dưới dạng một lớp lót với lệnh gọi tới regex_replace
:
#include <string>
#include <regex>
using std::string;
string do_replace( string const & in, string const & from, string const & to )
{
return std::regex_replace( in, std::regex(from), to );
}
string test = "Remove all spaces";
std::cout << do_replace(test, " ", "") << std::endl;
đầu ra:
Removeallspaces
from
có thể là một biểu thức chính quy - vì vậy bạn có thể sử dụng các tiêu chí đối sánh phức tạp hơn nếu cần. Điều tôi không thấy là cách thực hiện điều này mà không áp dụng một số dạng phân tích cú pháp biểu thức chính quy - thay vào đó chỉ sử dụng diễn giải trực tiếp các from
ký tự.
Tại sao không trả về một chuỗi đã sửa đổi?
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;
}
Nếu bạn cần hiệu suất, đây là một hàm được tối ưu hóa để sửa đổi chuỗi đầu vào, nó không tạo bản sao của chuỗi:
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();
}
}
Kiểm tra:
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 changed: "
<< input << std::endl;
ReplaceStringInPlace(input, "bc", "??");
std::cout << "ReplaceStringInPlace() input string modified: "
<< input << std::endl;
Đầu ra:
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
Tính năng tìm và thay thế tại chỗ nội tuyến được tạo mẫu của tôi:
template<class T>
int inline findAndReplace(T& source, const T& find, const T& replace)
{
int num=0;
typename T::size_t fLen = find.size();
typename T::size_t rLen = replace.size();
for (T::size_t pos=0; (pos=source.find(find, pos))!=T::npos; pos+=rLen)
{
num++;
source.replace(pos, fLen, replace);
}
return num;
}
Nó trả về số lượng các mục được thay thế (để sử dụng nếu bạn muốn chạy liên tục, v.v.). Để dùng nó:
std::string str = "one two three";
int n = findAndReplace(str, "one", "1");
Cách dễ nhất (cung cấp một cái gì đó gần với những gì bạn đã viết) là sử dụng Boost.Regex , cụ thể là regex_replace .
std :: string đã tích hợp sẵn các phương thức find () và Replace (), nhưng chúng khó làm việc hơn vì chúng yêu cầu xử lý các chỉ số và độ dài chuỗi.
Tôi tin rằng điều này sẽ hiệu quả. Nó nhận const char * 's làm tham số.
//params find and replace cannot be NULL
void FindAndReplace( std::string& source, const char* find, const char* replace )
{
//ASSERT(find != NULL);
//ASSERT(replace != NULL);
size_t findLen = strlen(find);
size_t replaceLen = strlen(replace);
size_t pos = 0;
//search for the next occurrence of find within source
while ((pos = source.find(find, pos)) != std::string::npos)
{
//replace the found string with the replacement
source.replace( pos, findLen, replace );
//the next line keeps you from searching your replace string,
//so your could replace "hello" with "hello world"
//and not have it blow chunks.
pos += replaceLen;
}
}
size_type
đối với một chuỗi là unsigned
, >=
điều kiện kiểm tra của bạn trong vòng lặp sẽ luôn là true
. Bạn phải sử dụng std::string::npos
ở đó.
roll_down_window
// Replace all occurrences of searchStr in str with replacer
// Each match is replaced only once to prevent an infinite loop
// The algorithm iterates once over the input and only concatenates
// to the output, so it should be reasonably efficient
std::string replace(const std::string& str, const std::string& searchStr,
const std::string& replacer)
{
// Prevent an infinite loop if the input is empty
if (searchStr == "") {
return str;
}
std::string result = "";
size_t pos = 0;
size_t pos2 = str.find(searchStr, pos);
while (pos2 != std::string::npos) {
result += str.substr(pos, pos2-pos) + replacer;
pos = pos2 + searchStr.length();
pos2 = str.find(searchStr, pos);
}
result += str.substr(pos, str.length()-pos);
return result;
}
#include <string>
using std::string;
void myReplace(string& str,
const string& oldStr,
const string& newStr) {
if (oldStr.empty()) {
return;
}
for (size_t pos = 0; (pos = str.find(oldStr, pos)) != string::npos;) {
str.replace(pos, oldStr.length(), newStr);
pos += newStr.length();
}
}
Việc kiểm tra oldStr trống là điều quan trọng. Nếu vì bất cứ lý do gì mà tham số đó trống, bạn sẽ bị mắc kẹt trong một vòng lặp vô hạn.
Nhưng đúng vậy, hãy sử dụng giải pháp C ++ 11 hoặc Boost đã được thử và kiểm tra nếu bạn có thể.