1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
let replace ?(pos = 0) ?len ?(all = true) re ~f s =
if pos < 0 then invalid_arg "Re.replace";
let limit =
match len with
| None -> String.length s
| Some l ->
if l < 0 || pos + l > String.length s then invalid_arg "Re.replace";
pos + l
in
let buf = Buffer.create (String.length s) in
let rec iter pos on_match =
if pos <= limit
then (
match
Compile.match_str ~groups:true ~partial:false re s ~pos ~len:(limit - pos)
with
| Match substr ->
let p1, p2 = Group.offset substr 0 in
if pos = p1 && p1 = p2 && on_match
then (
if p2 < limit then Buffer.add_char buf s.[p2];
iter (p2 + 1) false)
else (
Buffer.add_substring buf s pos (p1 - pos);
let replacing = f substr in
Buffer.add_string buf replacing;
if all
then
iter
(if p1 = p2
then (
if p2 < limit then Buffer.add_char buf s.[p2];
p2 + 1)
else p2)
(p1 <> p2)
else Buffer.add_substring buf s p2 (limit - p2))
| Running _ -> ()
| Failed -> Buffer.add_substring buf s pos (limit - pos))
in
iter pos false;
Buffer.contents buf
;;
let replace_string ?pos ?len ?all re ~by s = replace ?pos ?len ?all re s ~f:(fun _ -> by)