하위 문자열의 모든 발생을 다른 문자열로 바꾸는 방법이 std::string
있습니까?
예를 들면 :
void SomeFunction(std::string& str)
{
str = str.replace("hello", "world"); //< I'm looking for something nice like this
}
답변:
자신의 교체를 구현하지 않는 이유는 무엇입니까?
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");
다음은 replace_all에 대한 공식 문서 입니다.
replace_all
12.3 모든 버전의 <대한 후원 썬 스튜디오에> 1.43의 버전 세그 폴트 것
boost
임베디드 장치에서 컴파일 시간이 상당히 늘어납니다. ARMv7 쿼드 코어도 있습니다. 100 줄의 코드가 2 분 안에 부스트없이 2 초 만에 컴파일됩니다.
C ++ 11에서는 다음을 호출하여 한 줄로이 작업을 수행 할 수 있습니다 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;
산출:
Removeallspaces
from
정규 표현식이 될 수 있으므로 필요한 경우 더 정교한 일치 기준을 사용할 수 있습니다. 내가 보지 못하는 것은 문자를 직접 해석하는 대신 정규식 구문 분석 을 적용 하지 않고 이를 수행하는 방법 from
입니다.
수정 된 문자열을 반환하지 않는 이유는 무엇입니까?
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;
}
성능이 필요한 경우 다음은 입력 문자열을 수정하는 최적화 된 함수이며 문자열의 복사본을 생성하지 않습니다.
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();
}
}
테스트 :
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;
산출:
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
내 템플릿 인라인 내부 찾기 및 바꾸기 :
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;
}
대체 된 항목 수를 반환합니다 (연속적으로 실행하려는 경우 등에 사용). 그것을 사용하려면 :
std::string str = "one two three";
int n = findAndReplace(str, "one", "1");
가장 쉬운 방법 (작성한 내용에 가까운 것을 제공)은 Boost.Regex , 특히 regex_replace 를 사용하는 것 입니다.
std :: string에는 find () 및 replace () 메서드가 내장되어 있지만 인덱스 및 문자열 길이를 처리해야하므로 작업하기가 더 복잡합니다.
나는 이것이 효과가있을 것이라고 믿는다. const char *를 매개 변수로 사용합니다.
//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
문자열 인에 대한 unsigned
당신의 >=
루프 조건에서 검사가 항상있을 것입니다 true
. 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();
}
}
oldStr이 비어 있는지 확인하는 것이 중요합니다. 어떤 이유로 든 해당 매개 변수가 비어 있으면 무한 루프에 갇히게됩니다.
하지만 가능하다면 시도되고 테스트 된 C ++ 11 또는 Boost 솔루션을 사용하십시오.