alternative to #21914; split, rsplit now forbid an empty separator (#21961)

This commit is contained in:
ringabout
2023-05-30 19:40:09 +08:00
committed by GitHub
parent 7e055413f9
commit 40f88da90b
3 changed files with 37 additions and 4 deletions

View File

@@ -255,6 +255,7 @@
- Pragma `{.inline.}` generates `__forceinline` if `__has_attribute(__forceinline)` for GCC and Clang.
- `strutils.split` and `strutils.rsplit` now forbid an empty separator.
## Standard library additions and changes

View File

@@ -487,12 +487,15 @@ iterator split*(s: string, seps: set[char] = Whitespace,
## "22"
## "08"
## "08.398990"
##
## .. warning:: `seps` should not be empty.
##
## See also:
## * `rsplit iterator<#rsplit.i,string,set[char],int>`_
## * `splitLines iterator<#splitLines.i,string>`_
## * `splitWhitespace iterator<#splitWhitespace.i,string,int>`_
## * `split func<#split,string,set[char],int>`_
assert seps.card > 0, "Empty separator"
splitCommon(s, seps, maxsplit, 1)
iterator split*(s: string, sep: string, maxsplit: int = -1): string =
@@ -512,11 +515,14 @@ iterator split*(s: string, sep: string, maxsplit: int = -1): string =
## "is"
## "corrupted"
##
## .. warning:: `sep` should not be empty.
##
## See also:
## * `rsplit iterator<#rsplit.i,string,string,int,bool>`_
## * `splitLines iterator<#splitLines.i,string>`_
## * `splitWhitespace iterator<#splitWhitespace.i,string,int>`_
## * `split func<#split,string,string,int>`_
assert sep.len > 0, "Empty separator"
splitCommon(s, sep, maxsplit, sep.len)
@@ -585,13 +591,16 @@ iterator rsplit*(s: string, seps: set[char] = Whitespace,
## "bar"
## "foo"
##
## Substrings are separated from the right by the set of chars `seps`
## Substrings are separated from the right by the set of chars `seps`.
##
## .. warning:: `seps` should not be empty.
##
## See also:
## * `split iterator<#split.i,string,set[char],int>`_
## * `splitLines iterator<#splitLines.i,string>`_
## * `splitWhitespace iterator<#splitWhitespace.i,string,int>`_
## * `rsplit func<#rsplit,string,set[char],int>`_
assert seps.card > 0, "Empty separator"
rsplitCommon(s, seps, maxsplit, 1)
iterator rsplit*(s: string, sep: string, maxsplit: int = -1,
@@ -610,13 +619,16 @@ iterator rsplit*(s: string, sep: string, maxsplit: int = -1,
## "bar"
## "foo"
##
## Substrings are separated from the right by the string `sep`
## Substrings are separated from the right by the string `sep`.
##
## .. warning:: `sep` should not be empty.
##
## See also:
## * `split iterator<#split.i,string,string,int>`_
## * `splitLines iterator<#splitLines.i,string>`_
## * `splitWhitespace iterator<#splitWhitespace.i,string,int>`_
## * `rsplit func<#rsplit,string,string,int>`_
assert sep.len > 0, "Empty separator"
rsplitCommon(s, sep, maxsplit, sep.len)
iterator splitLines*(s: string, keepEol = false): string =
@@ -728,6 +740,8 @@ func split*(s: string, seps: set[char] = Whitespace, maxsplit: int = -1): seq[
## The same as the `split iterator <#split.i,string,set[char],int>`_ (see its
## documentation), but is a func that returns a sequence of substrings.
##
## .. warning:: `seps` should not be empty.
##
## See also:
## * `split iterator <#split.i,string,set[char],int>`_
## * `rsplit func<#rsplit,string,set[char],int>`_
@@ -745,6 +759,8 @@ func split*(s: string, sep: string, maxsplit: int = -1): seq[string] {.rtl,
## Substrings are separated by the string `sep`. This is a wrapper around the
## `split iterator <#split.i,string,string,int>`_.
##
## .. warning:: `sep` should not be empty.
##
## See also:
## * `split iterator <#split.i,string,string,int>`_
## * `rsplit func<#rsplit,string,string,int>`_
@@ -757,8 +773,6 @@ func split*(s: string, sep: string, maxsplit: int = -1): seq[string] {.rtl,
doAssert "a largely spaced sentence".split(" ") == @["a", "", "largely",
"", "", "", "spaced", "sentence"]
doAssert "a largely spaced sentence".split(" ", maxsplit = 1) == @["a", " largely spaced sentence"]
doAssert(sep.len > 0)
accResult(split(s, sep, maxsplit))
func rsplit*(s: string, sep: char, maxsplit: int = -1): seq[string] {.rtl,
@@ -808,6 +822,8 @@ func rsplit*(s: string, seps: set[char] = Whitespace,
## .. code-block:: nim
## @["Root#Object#Method", "Index"]
##
## .. warning:: `seps` should not be empty.
##
## See also:
## * `rsplit iterator <#rsplit.i,string,set[char],int>`_
## * `split func<#split,string,set[char],int>`_
@@ -835,6 +851,8 @@ func rsplit*(s: string, sep: string, maxsplit: int = -1): seq[string] {.rtl,
## .. code-block:: nim
## @["Root#Object#Method", "Index"]
##
## .. warning:: `sep` should not be empty.
##
## See also:
## * `rsplit iterator <#rsplit.i,string,string,int,bool>`_
## * `split func<#split,string,string,int>`_

View File

@@ -53,6 +53,13 @@ template main() =
doAssert s.split(maxsplit = 4) == @["", "this", "is", "an", "example "]
doAssert s.split(' ', maxsplit = 1) == @["", "this is an example "]
doAssert s.split(" ", maxsplit = 4) == @["", "this", "is", "an", "example "]
# Empty string:
doAssert "".split() == @[""]
doAssert "".split(" ") == @[""]
doAssert "".split({' '}) == @[""]
# Empty separators:
doAssertRaises(AssertionDefect): discard s.split({})
doAssertRaises(AssertionDefect): discard s.split("")
block: # splitLines
let fixture = "a\nb\rc\r\nd"
@@ -69,6 +76,13 @@ template main() =
doAssert rsplit(":foo:bar", sep = ':', maxsplit = 2) == @["", "foo", "bar"]
doAssert rsplit(":foo:bar", sep = ':', maxsplit = 3) == @["", "foo", "bar"]
doAssert rsplit("foothebar", sep = "the") == @["foo", "bar"]
# Empty string:
doAssert "".rsplit() == @[""]
doAssert "".rsplit(" ") == @[""]
doAssert "".rsplit({' '}) == @[""]
# Empty separators:
doAssertRaises(AssertionDefect): discard "".rsplit({})
doAssertRaises(AssertionDefect): discard "".rsplit("")
block: # splitWhitespace
let s = " this is an example "