2 * ExtString - Additional functions for string manipulations.
3 * Copyright (C) 2003 Nicolas Cannasse
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version,
9 * with the special exception on linking described in file LICENSE.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 exception Invalid_string
23 module String
= struct
29 for i
= 0 to len
- 1 do
34 let starts_with str p
=
35 if length str
< length p
then
38 let rec loop str p i
=
39 if i
= length p
then true else
40 if unsafe_get str i
<> unsafe_get p i
then false
46 if length
s < length e
then
50 if i
= length e
then true else
51 if unsafe_get
s (length
s - length e
+ i
) <> unsafe_get e i
then false
57 let sublen = length sub
in
62 let len = length str
in
64 for i
= 0 to len - sublen do
66 while unsafe_get str
(i
+ !j) = unsafe_get sub
!j do
68 if !j = sublen then begin found := i
; raise Exit
; end;
80 Invalid_string
-> false
82 let strip ?
(chars
=" \t\r\n") s =
85 while !p < l && contains chars
(unsafe_get
s !p) do
89 let l = ref (l - 1) in
90 while !l >= p && contains chars
(unsafe_get
s !l) do
96 let p = find str sep
in
97 let len = length sep
in
98 let slen = length str
in
99 sub str
0 p, sub str
(p + len) (slen - p - len)
103 else if sep
= "" then raise Invalid_string
105 let rec nsplit str sep
=
107 let s1 , s2
= split str sep
in
110 Invalid_string
-> [str
]
117 let slice ?
(first
=0) ?
(last
=Sys.max_string_length
) s =
118 let clip _min _max x
= max _min
(min _max x
) in
119 let i = clip 0 (length
s)
120 (if (first
<0) then (length
s) + first
else first
)
121 and j = clip 0 (length
s)
122 (if (last
<0) then (length
s) + last
else last
)
124 if i>=j || i=length
s then
130 if s = "" then "" else sub
s 1 (length
s - 1)
133 if s = "" then "" else sub
s 0 (length
s - 1)
135 let of_int = string_of_int
137 let of_float = string_of_float
145 _
-> raise Invalid_string
151 _
-> raise Invalid_string
159 raise
Enum.No_more_elements
165 ~count
:(fun () -> l - !i)
166 ~clone
:(fun () -> make (ref !i))
171 let l = Enum.count e
in
174 Enum.iter
(fun c
-> unsafe_set
s !i c
; incr
i) e
;
178 let len = length
s in
179 let sc = create
len in
180 for i = 0 to len - 1 do
181 unsafe_set
sc i (f
(unsafe_get
s i))
185 (* fold_left and fold_right by Eric C. Cooper *)
186 let fold_left f
init str
=
187 let n = String.length str
in
188 let rec loop i result
=
190 else loop (i + 1) (f result str
.[i])
194 let fold_right f str
init =
195 let n = String.length str
in
196 let rec loop i result
=
200 loop i'
(f str
.[i'
] result
)
204 (* explode and implode from the OCaml Expert FAQ. *)
207 if i < 0 then l else exp (i - 1) (s.[i] :: l) in
208 exp (String.length
s - 1) []
211 let res = String.create
(List.length
l) in
212 let rec imp i = function
214 | c
:: l -> res.[i] <- c
; imp (i + 1) l in
218 let replace_chars f
s =
219 let len = String.length
s in
225 let s = f
(unsafe_get
s i) in
226 tlen := !tlen + length
s;
227 loop (i+1) (s :: acc
)
229 let strs = loop 0 [] in
230 let sbuf = create
!tlen in
231 let pos = ref !tlen in
232 let rec loop2 = function
235 let len = length
s in
237 blit
s 0 sbuf !pos len;
243 let replace ~str ~sub ~by
=
245 let i = find str sub
in
246 (true, (slice ~last
:i str
) ^ by ^
247 (slice ~first
:(i+(String.length sub
)) str
))
249 Invalid_string
-> (false, String.copy str
)