1#' Replace substrings within a string.
2#'
3#' Return a copy of the string with all occurrences of substring \code{old} replaced by \code{new}.
4#'
5#' If the optional argument \code{count} is given, only the first \code{count} occurrences are replaced.
6#'
7#' @param str A character vector.
8#' @param old A character vector.
9#' @param new A character vector.
10#' @param count A numeric vector.
11#'
12#' @return A character vector.
13#'
14#' @references \url{https://docs.python.org/3/library/stdtypes.html#str.replace}
15#'
16#' @examples
17#' pystr_replace("123123123", "2", "two")
18#' pystr_replace("123123123", "2", "two", 2)
19#'
20#' @export
21pystr_replace <- function(str, old, new, count=nchar(str) + 2) {
22  return(mapply(pystr_replace_, str, old, new, count, USE.NAMES=FALSE))
23}
24
25pystr_replace_ <- function(str, old, new, count) {
26  if(count == 0) {
27    return(str)
28  }
29
30  if(old == "") {
31    separated = pystr_split(str, "", count - 1)
32    joined = paste0(new, pystr_join(separated, new))
33
34    if(count == nchar(str) + 2) {
35      return(paste0(joined, new))
36    }
37
38    return(joined)
39  }
40
41  num_replaces = min(pystr_count(str, old), count)
42  cum_replaces = 0
43  replaced = ""
44  remaining = str
45
46  while(cum_replaces < num_replaces) {
47    parts = pystr_split(remaining, old, 1)[[1]]
48    replaced = paste0(replaced, parts[1], new)
49    remaining = parts[2]
50    cum_replaces = cum_replaces + 1
51  }
52
53  return(paste0(replaced, remaining))
54}
55