Added two new optional arguments to nsplit: * noempty: if set to false empty elements are not stored in the returned list. The default is to keep the empty elements * count: specifies how many splits to perform; negative count (the default) means do as many splits as possible Added tests for nsplit. Signed-off-by: Tomáš Golembiovský <tgolembi@redhat.com> --- mllib/common_utils.ml | 12 +++++++++--- mllib/common_utils.mli | 12 ++++++++++-- mllib/common_utils_tests.ml | 26 ++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml index f948dce..b6f3046 100644 --- a/mllib/common_utils.ml +++ b/mllib/common_utils.ml @@ -130,15 +130,21 @@ module String = struct done; if not !r then s else Bytes.to_string b2 - let rec nsplit sep str = + let rec nsplit ?(noempty = true) ?(count = -1) sep str = let len = length str in let seplen = length sep in let i = find str sep in - if i = -1 then [str] + if i = -1 || count = 0 then [str] else ( let s' = sub str 0 i in let s'' = sub str (i+seplen) (len-i-seplen) in - s' :: nsplit sep s'' + let elem, count = + if s' = "" && noempty then + [], count + else + [s'], if count > 0 then count-1 else count + in + elem @ nsplit ~noempty:noempty ~count:count sep s'' ) let split sep str = diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli index 4a6ddd6..fd0ef49 100644 --- a/mllib/common_utils.mli +++ b/mllib/common_utils.mli @@ -80,9 +80,17 @@ module String : sig [str] with [s2]. *) val replace_char : string -> char -> char -> string (** Replace character in string. *) - val nsplit : string -> string -> string list + val nsplit : ?noempty:bool -> ?count:int -> string -> string -> string list (** [nsplit sep str] splits [str] into multiple strings at each - separator [sep]. *) + separator [sep]. + + If [noempty] is set to true empty elements are not included in the + list. By default empty elements are kept. + + If [count] is specified it says how many splits to perform. I.e. the + returned array will have at most [count]+1 elements. Negative [count] + (the default) means do as many splits as possible. + *) val split : string -> string -> string * string (** [split sep str] splits [str] at the first occurrence of the separator [sep], returning the part before and the part after. diff --git a/mllib/common_utils_tests.ml b/mllib/common_utils_tests.ml index ee27b93..ef5665f 100644 --- a/mllib/common_utils_tests.ml +++ b/mllib/common_utils_tests.ml @@ -109,6 +109,32 @@ let test_string_find ctx = assert_equal_int (-1) (String.find "" "baz"); assert_equal_int (-1) (String.find "foobar" "baz") +(* Test Common_utils.String.nsplit *) +let test_string_nsplit ctx = + (* Basic functionality *) + assert_equal_stringlist [""] (String.nsplit "," ""); + assert_equal_stringlist ["A"] (String.nsplit "," "A"); + assert_equal_stringlist ["A"; "B"] (String.nsplit "," "A,B"); + assert_equal_stringlist ["A"; "B"; "C"] (String.nsplit "," "A,B,C"); + assert_equal_stringlist ["A"; "B"; "C"; "D"] (String.nsplit "," "A,B,C,D"); + assert_equal_stringlist [""; "A"; ""] (String.nsplit "," ",A,"); + assert_equal_stringlist ["A"; ""; ""; "B"] (String.nsplit "," "A,,,B"); + assert_equal_stringlist ["A"; "B"; "C"; "D"] (String.nsplit "<>" "A<>B<>C<>D"); + + (* noemty option *) + assert_equal_stringlist ["A"] (String.nsplit ~noempty:true "," ",A,"); + assert_equal_stringlist ["A"; "B"] (String.nsplit ~noempty:true "," "A,,,B"); + + (* count option *) + assert_equal_stringlist ["A"; "B"; "C"; "D"] (String.nsplit ~count:(-1) "," "A,B,C,D"); + assert_equal_stringlist ["A,B,C,D"] (String.nsplit ~count:0 "," "A,B,C,D"); + assert_equal_stringlist ["A"; "B,C,D"] (String.nsplit ~count:1 "," "A,B,C,D"); + assert_equal_stringlist ["A"; "B"; "C,D"] (String.nsplit ~count:2 "," "A,B,C,D"); + assert_equal_stringlist ["A"; "B"; "C"; "D"] (String.nsplit ~count:10 "," "A,B,C,D"); + + (* count and noempty together *) + assert_equal_stringlist ["A"; "B"; "C,D"] (String.nsplit ~noempty:true ~count:2 "," ",,,A,,,,B,,,,C,D") + (* Test Common_utils.String.lines_split. *) let test_string_lines_split ctx = assert_equal_stringlist [""] (String.lines_split ""); -- 2.10.2