Skip to content

Instantly share code, notes, and snippets.

@rixed
Created May 23, 2013 19:36
Show Gist options
  • Save rixed/5638817 to your computer and use it in GitHub Desktop.
Save rixed/5638817 to your computer and use it in GitHub Desktop.
Alternative for nreplace
let nreplace ~str ~sub ~by =
let strlen = length str in
let sublen = length sub in
let bylen = length by in
let dlen = bylen - sublen in
let rec loop_subst l i =
match Exceptionless.rfind_from str (i-1) sub with
| None -> l
| Some i' -> loop_subst (l + dlen) i' in
let newlen =
if dlen = 0 then strlen else loop_subst strlen strlen in
let newstr = create newlen in
let rec loop_copy i j =
match Exceptionless.rfind_from str (i-1) sub with
| None ->
(* still need the first chunk *)
assert (i = j) ;
blit str 0 newstr 0 i
| Some i' ->
let j' = j - (i - i') - dlen in
(* newstring.[j .. end] is already inited. Init from j' to (j-1). *)
blit by 0 newstr j' bylen ;
blit str (i'+sublen) newstr (j'+bylen) (i-i'-sublen) ;
loop_copy i' j' in
loop_copy strlen newlen ;
newstr
@thelema
Copy link

thelema commented May 23, 2013

My original thought was to store the offsets when scanning the first time so you don't have to scan the original string twice; i.e. building up a recipe for how to construct the final string.

@thelema
Copy link

thelema commented May 23, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment