Skip to content

Commit 43f2ee6

Browse files
committed
Merge pull request #479 from thirdwing/master
Fix the string replace
2 parents 7efcd67 + 1dc0486 commit 43f2ee6

File tree

2 files changed

+14
-9
lines changed

2 files changed

+14
-9
lines changed

inst/include/Rcpp/String.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ namespace Rcpp {
262262
RCPP_STRING_DEBUG_2("String::replace_first(const char* = '%s' , const char* = '%s')", s, news);
263263
if (is_na()) return *this;
264264
setBuffer();
265-
size_t index = buffer.find_first_of(s);
265+
std::string s2 = std::string(s);
266+
size_t index = std::distance(buffer.begin(), std::search(buffer.begin(), buffer.end(), s2.begin(), s2.end()));
266267
if (index != std::string::npos) buffer.replace(index, strlen(s), news);
267268
valid = false;
268269
return *this;
@@ -287,7 +288,8 @@ namespace Rcpp {
287288
RCPP_STRING_DEBUG_2("String::replace_last(const char* = '%s' , const char* = '%s')", s, news);
288289
if (is_na()) return *this;
289290
setBuffer();
290-
size_t index = buffer.find_last_of(s);
291+
std::string s2 = std::string(s);
292+
size_t index = std::distance(buffer.begin(), std::find_end(buffer.begin(), buffer.end(), s2.begin(), s2.end()));
291293
if (index != std::string::npos) buffer.replace(index, strlen(s), news);
292294
valid = false;
293295
return *this;
@@ -313,10 +315,13 @@ namespace Rcpp {
313315
RCPP_STRING_DEBUG_2("String::replace_all(const char* = '%s' , const char* = '%s')", s, news);
314316
if (is_na()) return *this;
315317
setBuffer();
316-
size_t lens = strlen(s), len_news = strlen(news), index = buffer.find(s);
317-
while(index != std::string::npos) {
318-
buffer.replace(index, lens, news);
319-
index = buffer.find(s, index + len_news);
318+
std::string s2 = std::string(s);
319+
std::string::iterator iter = buffer.begin();
320+
while(true) {
321+
iter = std::search(iter, buffer.end(), s2.begin(), s2.end());
322+
if (iter == buffer.end()) break;
323+
size_t index = std::distance(buffer.begin(), iter);
324+
if (index != std::string::npos) buffer.replace(index, strlen(s), news);
320325
}
321326
valid = false;
322327
return *this;

inst/unitTests/runit.String.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ if (.runThisTest) {
2424
.setUp <- Rcpp:::unitTestSetup("String.cpp")
2525

2626
test.replace_all <- function(){
27-
checkEquals( String_replace_all("foobar", "o", "*"), "f**bar")
27+
checkEquals( String_replace_all("abcdbacdab", "ab", "AB"), "ABcdbacdAB")
2828
}
2929
test.replace_first <- function(){
30-
checkEquals( String_replace_first("foobar", "o", "*"), "f*obar")
30+
checkEquals( String_replace_first("abcdbacdab", "ab", "AB"), "ABcdbacdab")
3131
}
3232
test.replace_last <- function(){
33-
checkEquals( String_replace_last("foobar", "o", "*"), "fo*bar")
33+
checkEquals( String_replace_last("abcdbacdab", "ab", "AB"), "abcdbacdAB")
3434
}
3535

3636
test.String.sapply <- function(){

0 commit comments

Comments
 (0)