Skip to content

Commit

Permalink
Implement Js.String2.replaceByRe
Browse files Browse the repository at this point in the history
  • Loading branch information
davesnx committed Aug 19, 2023
1 parent 3e3b465 commit f19328a
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
15 changes: 10 additions & 5 deletions packages/js/js.ml
Original file line number Diff line number Diff line change
Expand Up @@ -829,9 +829,12 @@ module String2 = struct
let splitByReAtMost _ _ = notImplemented "Js.String2" "splitByReAtMost"

let splitByRe str pattern =
let rev_array arr =
arr |> Stdlib.Array.to_list |> Stdlib.List.rev |> Stdlib.Array.of_list
in
let rec split_all str acc =
match Re.exec_ pattern str with
| None -> List.rev (str :: acc)
| None -> Stdlib.Array.append [| Some str |] acc |> rev_array
| Some result ->
Re.setLastIndex pattern 0;
let matches = Re.matches result in
Expand All @@ -841,24 +844,26 @@ module String2 = struct
let suffix =
String.sub str suffix_start (String.length str - suffix_start)
in
split_all suffix (prefix :: acc)
let suffix_matches = Stdlib.Array.append [| Some prefix |] acc in
split_all suffix suffix_matches
in

let split_next str acc =
match Re.exec_ pattern str with
| None -> List.rev (str :: acc)
| None -> Stdlib.Array.append [| Some str |] acc |> rev_array
| Some result ->
Re.setLastIndex pattern 0;
let matches = Re.matches result in
let matched_str = Stdlib.Array.get matches 0 in
let prefix = String.sub str 0 (Re.index result) in
let suffix_start = Re.index result + String.length matched_str in
let suffix =
String.sub str suffix_start (String.length str - suffix_start)
in
prefix :: split_all suffix acc
Stdlib.Array.append [| Some prefix |] (split_all suffix acc)
in

if Re.global pattern then split_all str [] else split_next str []
if Re.global pattern then split_all str [||] else split_next str [||]

let startsWith str prefix =
Stdlib.String.length prefix <= Stdlib.String.length str
Expand Down
15 changes: 12 additions & 3 deletions packages/js/test.ml
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,18 @@ let string2_tests =
[| "ant"; "bee"; "cat"; "dog"; "elk" |] *)
());
case "splitByRe" (fun () ->
(* assert_string_array (splitByRe [%re "/\\s*[,;]\\s*/"] "art; bed , cog ;dad") [| Some "art"; Some "bed"; Some "cog"; Some "dad" |];
assert_string_array (splitByRe [%re "/[,;]/"] "has:no:match" [| Some "has:no:match" |] splitByRe [%re "/(#)(:)?/"] "a#b#:c") [|Some "a"; Some "#"; None; Some "b"; Some "#"; Some ":"; Some "c"; |]; *)
());
let unsafe_splitByRe r s =
Js.String2.splitByRe r s |> Stdlib.Array.map Stdlib.Option.get
in
assert_string_array
(unsafe_splitByRe "art; bed , cog ;dad" [%re "/\\s*[,;]\\s*/"])
[| "art"; "bed"; "cog"; "dad" |];
assert_string_array
(unsafe_splitByRe "has:no:match" [%re "/[,;]/"])
[| "has:no:match" |];
assert_string_array
(unsafe_splitByRe "a#b#c" [%re "/(#)(:)?/g"])
[| "a"; "b"; "c" |]);
case "splitByReAtMost" (fun () ->
(* assert_string_array
(splitByReAtMost [%re "/\\s*:\\s*/"] ~limit:3
Expand Down

0 comments on commit f19328a

Please sign in to comment.