C ++에서 문자열의 일부를 다른 문자열로 바꿀 수 있습니까?
기본적 으로이 작업을 수행하고 싶습니다.
QString string("hello $name");
string.replace("$name", "Somename");
그러나 Standard C ++ 라이브러리를 사용하고 싶습니다.
C ++에서 문자열의 일부를 다른 문자열로 바꿀 수 있습니까?
기본적 으로이 작업을 수행하고 싶습니다.
QString string("hello $name");
string.replace("$name", "Somename");
그러나 Standard C ++ 라이브러리를 사용하고 싶습니다.
답변:
문자열 ( find
) 내에서 하위 문자열을 찾는 기능 과 문자열 의 특정 범위를 다른 문자열 ( replace
) 로 바꾸는 기능이 있으므로 원하는 효과를 얻기 위해 이들을 결합 할 수 있습니다.
bool replace(std::string& str, const std::string& from, const std::string& to) {
size_t start_pos = str.find(from);
if(start_pos == std::string::npos)
return false;
str.replace(start_pos, from.length(), to);
return true;
}
std::string string("hello $name");
replace(string, "$name", "Somename");
의견에 대한 응답으로 replaceAll
아마도 다음과 같이 보일 것입니다.
void replaceAll(std::string& str, const std::string& from, const std::string& to) {
if(from.empty())
return;
size_t start_pos = 0;
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
}
}
from
및 to
당 통과 const
참조? from
없는 경우 기능 은 무엇입니까 ? -1
저 한테 서요
const
이와 같은 유틸리티 메소드를 작성하면 내가 알고있는 경우에만 호출합니다. 교체가 유효
const
는 C ++ 최고의 도구 중 하나를 무시합니다. 함수 매개 변수의 기본 모드 는 const
참조 당 전달 이어야합니다. (FTR을 사용하지 const
않으면 임시 const
참조 를 비 참조에 바인딩 할 수 없으므로 문자열 리터럴을 함수에 전달할 수도 없습니다 . 따라서 함수는 작성된 내용을 수행하지도 않습니다.)
C ++ 11을 사용하면 다음 std::regex
과 같이 사용할 수 있습니다 .
#include <regex>
...
std::string string("hello $name");
string = std::regex_replace(string, std::regex("\\$name"), "Somename");
이스케이프 문자를 이스케이프 처리하려면 이중 백 슬래시가 필요합니다.
std::regex_replace
Qt의 문자열을 받아들이지 않을 것이라고 확신 합니다.
string
하여 수정할 수 있다고 생각 string.toStdString()
합니다.
String
하면 std::string
됩니다. 그 일을 고려하십시오-나중에 귀하의 답변을 기꺼이 찬송하겠습니다.
R"(\$name)"
대신 쓸 수 있습니다 "\\$name"
.
std::string
가 replace
당신을 위해 무엇을 찾고있는 것을, 방법을 무엇입니까?
시도해 볼 수 있습니다 :
s.replace(s.find("$name"), sizeof("$name") - 1, "Somename");
난 그냥에 대한 설명서를 읽고, 자신을 시도하지 않은 find()
및 replace()
.
새 문자열을 반환하려면 다음을 사용하십시오.
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 modified: "
<< 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
예, 할 수 있지만 string의 find () 멤버로 첫 번째 문자열의 위치를 찾은 다음 replace () 멤버로 바꿔야합니다.
string s("hello $name");
size_type pos = s.find( "$name" );
if ( pos != string::npos ) {
s.replace( pos, 5, "somename" ); // 5 = length( $name )
}
표준 라이브러리를 사용할 계획이라면, 이 모든 것들을 아주 잘 다루는 C ++ 표준 라이브러리 책 의 사본을 실제로 얻어야 합니다.
나는 일반적으로 이것을 사용한다 :
std::string& replace(std::string& s, const std::string& from, const std::string& to)
{
if(!from.empty())
for(size_t pos = 0; (pos = s.find(from, pos)) != std::string::npos; pos += to.size())
s.replace(pos, from.size(), to);
return s;
}
아무것도 찾을 std::string::find()
때까지 검색된 문자열의 다른 항목을 찾기 위해 반복적으로 호출 합니다 std::string::find()
. 일치 std::string::find()
하는 위치 를 반환 하기 때문에 반복자를 무효화하는 데 문제가 없습니다.
이것은 옵션처럼 들립니다
string.replace(string.find("%s"), string("%s").size(), "Something");
이것을 함수로 포장 할 수는 있지만이 한 줄 솔루션은 받아 들일 수 있습니다. 문제는 이것이 첫 번째 발생만을 변경한다는 것입니다. 반복하고 싶을 수도 있지만 동일한 토큰 ( %s
) 을 사용 하여이 문자열에 여러 변수를 삽입 할 수도 있습니다
str.replace(str.find("%s"), string("%s").size(), "Something");
모든 문자열이 std :: string 인 경우 sizeof()
C ++ 문자열이 아닌 C 문자열에 사용 되므로 문자 컷오프에 이상한 문제가 있습니다. 수정은의 .size()
클래스 메소드 를 사용하는 것입니다 std::string
.
sHaystack.replace(sHaystack.find(sNeedle), sNeedle.size(), sReplace);
그것은 sHaystack 인라인을 대체합니다-다시 할당 할 필요가 없습니다.
사용법 예 :
std::string sHaystack = "This is %XXX% test.";
std::string sNeedle = "%XXX%";
std::string sReplace = "my special";
sHaystack.replace(sHaystack.find(sNeedle),sNeedle.size(),sReplace);
std::cout << sHaystack << std::endl;
wstring myString = L"Hello $$ this is an example. By $$.";
wstring search = L"$$";
wstring replace = L"Tom";
for (int i = myString.find(search); i >= 0; i = myString.find(search))
myString.replace(i, search.size(), replace);
빠르게하려면 두 가지 스캔 방법을 사용할 수 있습니다. 의사 코드 :
이것이 내부 알고리즘에 최적화 될 수 있는지 잘 모르겠습니다.
그리고 C ++ 11 코드 예제이지만 하나의 문자 만 검색합니다.
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
void ReplaceString(string& subject, char search, const string& replace)
{
size_t initSize = subject.size();
int count = 0;
for (auto c : subject) {
if (c == search) ++count;
}
size_t idx = subject.size()-1 + count * replace.size()-1;
subject.resize(idx + 1, '\0');
string reverseReplace{ replace };
reverse(reverseReplace.begin(), reverseReplace.end());
char *end_ptr = &subject[initSize - 1];
while (end_ptr >= &subject[0])
{
if (*end_ptr == search) {
for (auto c : reverseReplace) {
subject[idx - 1] = c;
--idx;
}
}
else {
subject[idx - 1] = *end_ptr;
--idx;
}
--end_ptr;
}
}
int main()
{
string s{ "Mr John Smith" };
ReplaceString(s, ' ', "%20");
cout << s << "\n";
}
std::string replace(std::string base, const std::string from, const std::string to) {
std::string SecureCopy = base;
for (size_t start_pos = SecureCopy.find(from); start_pos != std::string::npos; start_pos = SecureCopy.find(from,start_pos))
{
SecureCopy.replace(start_pos, from.length(), to);
}
return SecureCopy;
}
문자열을 한 번만 크기 조정하면 교체가 발생할 수 있다는 점을 고려한 자체 구현입니다.
template <typename T>
std::basic_string<T> replaceAll(const std::basic_string<T>& s, const T* from, const T* to)
{
auto length = std::char_traits<T>::length;
size_t toLen = length(to), fromLen = length(from), delta = toLen - fromLen;
bool pass = false;
std::string ns = s;
size_t newLen = ns.length();
for (bool estimate : { true, false })
{
size_t pos = 0;
for (; (pos = ns.find(from, pos)) != std::string::npos; pos++)
{
if (estimate)
{
newLen += delta;
pos += fromLen;
}
else
{
ns.replace(pos, fromLen, to);
pos += delta;
}
}
if (estimate)
ns.resize(newLen);
}
return ns;
}
사용법은 예를 들어 다음과 같습니다.
std::string dirSuite = replaceAll(replaceAll(relPath.parent_path().u8string(), "\\", "/"), ":", "");
방금 C ++을 배우고 있지만 이전에 게시 한 코드 중 일부를 편집하면 아마도 이와 같은 것을 사용합니다. 이를 통해 하나 이상의 인스턴스를 유연하게 교체 할 수 있으며 시작점을 지정할 수도 있습니다.
using namespace std;
// returns number of replacements made in string
long strReplace(string& str, const string& from, const string& to, size_t start = 0, long count = -1) {
if (from.empty()) return 0;
size_t startpos = str.find(from, start);
long replaceCount = 0;
while (startpos != string::npos){
str.replace(startpos, from.length(), to);
startpos += to.length();
replaceCount++;
if (count > 0 && replaceCount >= count) break;
startpos = str.find(from, startpos);
}
return replaceCount;
}
이것은 사용하는 것이 더 나을 수 있습니다
void replace(string& input, const string& from, const string& to)
{
while(true)
{
size_t startPosition = input.find(from);
if(startPosition == string::npos)
break;
input.replace(startPosition, from.length(), to);
}
}