diff options
-rw-r--r-- | README.asciidoc | 4 | ||||
-rw-r--r-- | src/nre.nim | 7 | ||||
-rw-r--r-- | test/split.nim | 5 |
3 files changed, 14 insertions, 2 deletions
diff --git a/README.asciidoc b/README.asciidoc index 877ffce47..2fcc05ded 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -54,7 +54,7 @@ Variants: - `proc findAllStr(...)` returns a `seq[string]` [[proc-split]] -==== split(string, Regex): seq[string] +==== split(string, Regex, maxsplit = -1): seq[string] Splits the string with the given regex. This works according to the rules that Perl and Javascript use. @@ -63,6 +63,8 @@ Perl and Javascript use. `"123".split(r"") == @["1", "2", "3"]`. - If the pattern has a capture in it, it is added after the string split: `"12".split(re"(\d)") == @["", "1", "", "2", ""]`. + - If `maxsplit != -1`, then the string will only be split `maxsplit` times. + `"123".split(re"", maxsplit = 1) == @["1", "23"]` [[proc-replace]] ==== replace(string, Regex, sub): string diff --git a/src/nre.nim b/src/nre.nim index b66a1f6da..6ba5f560f 100644 --- a/src/nre.nim +++ b/src/nre.nim @@ -384,9 +384,10 @@ proc renderBounds(str: string, bounds: Slice[int]): string = for i in bounds.a .. bounds.b: result.add("^") -proc split*(str: string, pattern: Regex): seq[string] = +proc split*(str: string, pattern: Regex, maxSplit = -1): seq[string] = result = @[] var lastIdx = 0 + var splits = 0 for match in str.findIter(pattern): # upper bound is exclusive, lower is inclusive: @@ -405,6 +406,7 @@ proc split*(str: string, pattern: Regex): seq[string] = discard else: result.add(str.substr(lastIdx, bounds.a - 1)) + splits += 1 lastIdx = bounds.b @@ -412,6 +414,9 @@ proc split*(str: string, pattern: Regex): seq[string] = # if there are captures, include them in the result result.add(cap) + if splits == maxSplit: + break + # last match: Each match takes the previous substring, # but "1 2".split(/ /) needs to return @["1", "2"]. # This handles "2" diff --git a/test/split.nim b/test/split.nim index 8366f801f..838f06261 100644 --- a/test/split.nim +++ b/test/split.nim @@ -11,3 +11,8 @@ suite "string splitting": test "captured patterns": check("12".split(re"(\d)") == @["", "1", "", "2", ""]) + + test "maxsplit": + check("123".split(re"", maxsplit = 1) == @["1", "23"]) + check("123".split(re"", maxsplit = 0) == @["123"]) + check("123".split(re"", maxsplit = -1) == @["1", "2", "3"]) |