Merge pull request #100953 from AtnNn/splitStrings

Implement splitString using builtins.split

Changed files
+28 -21
lib
+14 -21
lib/strings.nix
···
*/
escapeNixString = s: escape ["$"] (builtins.toJSON s);
+
/* Turn a string into an exact regular expression
+
+
Type: string -> string
+
+
Example:
+
escapeRegex "[^a-z]*"
+
=> "\\[\\^a-z]\\*"
+
*/
+
escapeRegex = escape (stringToCharacters "\\[{()^$?*+|.");
+
/* Quotes a string if it can't be used as an identifier directly.
Type: string -> string
···
/* Cut a string with a separator and produces a list of strings which
were separated by this separator.
-
NOTE: this function is not performant and should never be used.
-
Example:
splitString "." "foo.bar.baz"
=> [ "foo" "bar" "baz" ]
···
*/
splitString = _sep: _s:
let
-
sep = addContextFrom _s _sep;
-
s = addContextFrom _sep _s;
-
sepLen = stringLength sep;
-
sLen = stringLength s;
-
lastSearch = sLen - sepLen;
-
startWithSep = startAt:
-
substring startAt sepLen s == sep;
-
-
recurse = index: startAt:
-
let cutUntil = i: [(substring startAt (i - startAt) s)]; in
-
if index <= lastSearch then
-
if startWithSep index then
-
let restartAt = index + sepLen; in
-
cutUntil index ++ recurse restartAt restartAt
-
else
-
recurse (index + 1) startAt
-
else
-
cutUntil sLen;
+
sep = builtins.unsafeDiscardStringContext _sep;
+
s = builtins.unsafeDiscardStringContext _s;
+
splits = builtins.filter builtins.isString (builtins.split (escapeRegex sep) s);
in
-
recurse 0 0;
+
map (v: addContextFrom _sep (addContextFrom _s v)) splits;
/* Return a string without the specified prefix, if the prefix matches.
+14
lib/tests/misc.nix
···
expected = [ "2001" "db8" "0" "0042" "" "8a2e" "370" "" ];
};
+
testSplitStringsRegex = {
+
expr = strings.splitString "\\[{}]()^$?*+|." "A\\[{}]()^$?*+|.B";
+
expected = [ "A" "B" ];
+
};
+
+
testSplitStringsDerivation = {
+
expr = take 3 (strings.splitString "/" (derivation {
+
name = "name";
+
builder = "builder";
+
system = "system";
+
}));
+
expected = ["" "nix" "store"];
+
};
+
testSplitVersionSingle = {
expr = versions.splitVersion "1";
expected = [ "1" ];