Add maxsplit

This commit is contained in:
Flaviu Tamas 2015-01-18 12:28:19 -05:00
commit 1bcaa21729
3 changed files with 14 additions and 2 deletions

View file

@ -54,7 +54,7 @@ Variants:
- `proc findAllStr(...)` returns a `seq[string]` - `proc findAllStr(...)` returns a `seq[string]`
[[proc-split]] [[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 Splits the string with the given regex. This works according to the rules that
Perl and Javascript use. Perl and Javascript use.
@ -63,6 +63,8 @@ Perl and Javascript use.
`"123".split(r"") == @["1", "2", "3"]`. `"123".split(r"") == @["1", "2", "3"]`.
- If the pattern has a capture in it, it is added after the string split: - If the pattern has a capture in it, it is added after the string split:
`"12".split(re"(\d)") == @["", "1", "", "2", ""]`. `"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]] [[proc-replace]]
==== replace(string, Regex, sub): string ==== replace(string, Regex, sub): string

View file

@ -384,9 +384,10 @@ proc renderBounds(str: string, bounds: Slice[int]): string =
for i in bounds.a .. bounds.b: for i in bounds.a .. bounds.b:
result.add("^") result.add("^")
proc split*(str: string, pattern: Regex): seq[string] = proc split*(str: string, pattern: Regex, maxSplit = -1): seq[string] =
result = @[] result = @[]
var lastIdx = 0 var lastIdx = 0
var splits = 0
for match in str.findIter(pattern): for match in str.findIter(pattern):
# upper bound is exclusive, lower is inclusive: # upper bound is exclusive, lower is inclusive:
@ -405,6 +406,7 @@ proc split*(str: string, pattern: Regex): seq[string] =
discard discard
else: else:
result.add(str.substr(lastIdx, bounds.a - 1)) result.add(str.substr(lastIdx, bounds.a - 1))
splits += 1
lastIdx = bounds.b lastIdx = bounds.b
@ -412,6 +414,9 @@ proc split*(str: string, pattern: Regex): seq[string] =
# if there are captures, include them in the result # if there are captures, include them in the result
result.add(cap) result.add(cap)
if splits == maxSplit:
break
# last match: Each match takes the previous substring, # last match: Each match takes the previous substring,
# but "1 2".split(/ /) needs to return @["1", "2"]. # but "1 2".split(/ /) needs to return @["1", "2"].
# This handles "2" # This handles "2"

View file

@ -11,3 +11,8 @@ suite "string splitting":
test "captured patterns": test "captured patterns":
check("12".split(re"(\d)") == @["", "1", "", "2", ""]) 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"])