···88888989### Standard library:
90909191+- #14362: Add String.{drop,take,cut}_{first,last}_while
9292+ (Daniel Bünzli, review by Nicolás Ojeda Bär and David Allsopp)
9393+9194- #14363: Preserve the backtrace at exceptional domain termination. Domain.join
9295 on an exceptionally terminated domain re-raises the exception with the
9396 backtrace.
···99102 (Leonardo Santos, review by Florian Angeletti and Gabriel Scherer)
100103101104- #14352: Add String.{drop,take,cut}_{first,last}.
102102- (Daniel Bünzli, review by David Allsopp, Vincent Laviron)
105105+ (Daniel Bünzli, review by David Allsopp, Nicolás Ojeda Bär and
106106+ Vincent Laviron)
103107104108- #14185: List.split_map
105109 (Jeremy Yallop, review by Daniel Bünzli, Nicolás Ojeda Bär and Damien Doligez)
+42
stdlib/string.ml
···243243let drop_last n s = subrange ~last:(length s - n - 1) s
244244let cut_last n s = (drop_last n s, take_last n s)
245245246246+(* Splitting with predicates *)
247247+248248+let take_first_while sat s =
249249+ let len = length s and i = ref 0 in
250250+ while !i < len && sat (unsafe_get s !i) do incr i done;
251251+ if !i = len then s else sub s 0 !i
252252+253253+let drop_first_while sat s =
254254+ let len = length s and i = ref 0 in
255255+ while !i < len && sat (unsafe_get s !i) do incr i done;
256256+ if !i = 0 then s else sub s !i (len - !i)
257257+258258+let cut_first_while sat s =
259259+ let len = length s and i = ref 0 in
260260+ while !i < len && sat (unsafe_get s !i) do incr i done;
261261+ if !i = len then s, "" else
262262+ if !i = 0 then "", s else
263263+ sub s 0 !i, sub s !i (len - !i)
264264+265265+let take_last_while sat s =
266266+ let len = length s in
267267+ let i = ref (len - 1) in
268268+ while !i >= 0 && sat (unsafe_get s !i) do decr i done;
269269+ if !i < 0 then s else
270270+ let j = !i + 1 in
271271+ sub s j (len - j)
272272+273273+let drop_last_while sat s =
274274+ let len = length s in
275275+ let i = ref (len - 1) in
276276+ while !i >= 0 && sat (unsafe_get s !i) do decr i done;
277277+ if !i < 0 then "" else sub s 0 (!i + 1)
278278+279279+let cut_last_while sat s =
280280+ let len = length s in
281281+ let i = ref (len - 1) in
282282+ while !i >= 0 && sat (unsafe_get s !i) do decr i done;
283283+ if !i < 0 then "", s else
284284+ if !i = len - 1 then s, "" else
285285+ let j = !i + 1 in
286286+ sub s 0 j, sub s j (len - j)
287287+246288(* Splitting with separators *)
247289248290(* duplicated in bytes.ml *)
+38
stdlib/string.mli
···230230231231 @since 5.5 *)
232232233233+(** {2:splitting_preds Splitting with predicates} *)
234234+235235+val take_first_while : (char -> bool) -> string -> string
236236+(** [take_first_while p s] is the first consecutive bytes of [s]
237237+ satisfying the predicate [p].
238238+239239+ @since 5.5 *)
240240+241241+val take_last_while : (char -> bool) -> string -> string
242242+(** [take_last_while p s] is the last consecutive bytes of [s]
243243+ satisfying the predicate [p].
244244+245245+ @since 5.5 *)
246246+247247+val drop_first_while : (char -> bool) -> string -> string
248248+(** [drop_first_while p s] is [s] without the first consecutive bytes of [s]
249249+ satisfying the predicate [p].
250250+251251+ @since 5.5 *)
252252+253253+val drop_last_while : (char -> bool) -> string -> string
254254+(** [drop_last_while p s] is [s] without the last consecutive bytes of [s]
255255+ satisfying the predicate [p].
256256+257257+ @since 5.5 *)
258258+259259+val cut_first_while : (char -> bool) -> string -> string * string
260260+(** [cut_first_while p s] is
261261+ [(take_first_while p s, drop_first_while p s)].
262262+263263+ @since 5.5 *)
264264+265265+val cut_last_while : (char -> bool) -> string -> string * string
266266+(** [cut_last_while p s] is
267267+ [(drop_last_while p s, take_last_while p s)].
268268+269269+ @since 5.5 *)
270270+233271(** {2:splitting_sep Splitting with separators} *)
234272235273val split_on_char : char -> string -> string list
+38
stdlib/stringLabels.mli
···230230231231 @since 5.5 *)
232232233233+(** {2:splitting_preds Splitting with predicates} *)
234234+235235+val take_first_while : (char -> bool) -> string -> string
236236+(** [take_first_while p s] is the first consecutive bytes of [s]
237237+ satisfying the predicate [p].
238238+239239+ @since 5.5 *)
240240+241241+val take_last_while : (char -> bool) -> string -> string
242242+(** [take_last_while p s] is the last consecutive bytes of [s]
243243+ satisfying the predicate [p].
244244+245245+ @since 5.5 *)
246246+247247+val drop_first_while : (char -> bool) -> string -> string
248248+(** [drop_first_while p s] is [s] without the first consecutive bytes of [s]
249249+ satisfying the predicate [p].
250250+251251+ @since 5.5 *)
252252+253253+val drop_last_while : (char -> bool) -> string -> string
254254+(** [drop_last_while p s] is [s] without the last consecutive bytes of [s]
255255+ satisfying the predicate [p].
256256+257257+ @since 5.5 *)
258258+259259+val cut_first_while : (char -> bool) -> string -> string * string
260260+(** [cut_first_while p s] is
261261+ [(take_first_while p s, drop_first_while p s)].
262262+263263+ @since 5.5 *)
264264+265265+val cut_last_while : (char -> bool) -> string -> string * string
266266+(** [cut_last_while p s] is
267267+ [(drop_last_while p s, take_last_while p s)].
268268+269269+ @since 5.5 *)
270270+233271(** {2:splitting_sep Splitting with separators} *)
234272235273val split_on_char : sep:char -> string -> string list