diff options
author | Silvan Mosberger <contact@infinisil.com> | 2020-10-20 22:12:52 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-20 22:12:52 +0200 |
commit | a2fe9a7abc68c5356ed7167bd9aae7ea201f2435 (patch) | |
tree | cdec1969619434d3eb4e6b4cfefe16962eb509b5 | |
parent | 6a94d64c101b977792cb7d1213855f4c20e5e838 (diff) | |
parent | d7464ab4bbb83694587bb2e217c032e0a6c0fd98 (diff) |
Merge pull request #100953 from AtnNn/splitStrings
Implement splitString using builtins.split
-rw-r--r-- | lib/strings.nix | 35 | ||||
-rw-r--r-- | lib/tests/misc.nix | 14 |
2 files changed, 28 insertions, 21 deletions
diff --git a/lib/strings.nix b/lib/strings.nix index 9fa9f023561e..d81e46a17631 100644 --- a/lib/strings.nix +++ b/lib/strings.nix @@ -315,6 +315,16 @@ rec { */ 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 @@ -386,8 +396,6 @@ rec { /* 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" ] @@ -396,26 +404,11 @@ rec { */ 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. diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 3a6db53c276d..6175f15819a7 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -154,6 +154,20 @@ runTests { 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" ]; |