From: Florent M. <fmo...@li...> - 2008-09-15 15:55:14
|
Hi, Here is an implementation for a function String.replace_all, it does the same than String.replace but for all occurences. Please tell me if you find it usefull, in which case I would provide a patch. let find_from str sub pos = let len = length str and sublen = length sub in if pos >= (len - sublen) then raise Invalid_string; if sublen = 0 then 0 else let found = ref 0 in try for i = pos to (len - sublen) do let j = ref 0 in while unsafe_get str (i + !j) = unsafe_get sub !j do incr j; if !j = sublen then begin found := i; raise Exit; end; done; done; raise Invalid_string with Exit -> !found let replace_all ~str ~sub ~by = let sublen = length sub in try if sublen = 0 then raise Invalid_string; let strlen = length str in let rec find_pos acc pos = try let i = find_from str sub pos in find_pos ((i + sublen)::i::acc) (i + sublen) with Invalid_string -> (strlen::acc) in let all_pos = (find_pos [0] 0) in if List.length all_pos = 2 then raise Invalid_string; let rec make_slices acc = function | [] -> acc | _::[] -> assert(false) | last::first::tl -> let this = slice ~first ~last str in make_slices (this::acc) tl in let slices = make_slices [] all_pos in let res = concat by slices in (true, res) with Invalid_string -> (false, String.copy str) -- Cheers Florent |