let subst patt repl s =
let lpatt = length patt in
let lrepl = length repl in
let rec loop s from =
match contains_string s from patt with
| Some pos ->
loop (before s pos ^ repl ^ after s (pos + lpatt)) (pos + lrepl)
| None -> s
in loop s 0