Fixed 7478: splitLines keepEol option (#8621)
This commit is contained in:
parent
e839c01f5b
commit
ee29370f60
2 changed files with 29 additions and 13 deletions
|
|
@ -624,12 +624,13 @@ iterator rsplit*(s: string, sep: string, maxsplit: int = -1,
|
||||||
## Substrings are separated from the right by the string `sep`
|
## Substrings are separated from the right by the string `sep`
|
||||||
rsplitCommon(s, sep, maxsplit, sep.len)
|
rsplitCommon(s, sep, maxsplit, sep.len)
|
||||||
|
|
||||||
iterator splitLines*(s: string): string =
|
iterator splitLines*(s: string, keepEol = false): string =
|
||||||
## Splits the string `s` into its containing lines.
|
## Splits the string `s` into its containing lines.
|
||||||
##
|
##
|
||||||
## Every `character literal <manual.html#character-literals>`_ newline
|
## Every `character literal <manual.html#character-literals>`_ newline
|
||||||
## combination (CR, LF, CR-LF) is supported. The result strings contain no
|
## combination (CR, LF, CR-LF) is supported. The result strings contain no
|
||||||
## trailing ``\n``.
|
## trailing end of line characters unless parameter ``keepEol`` is set to
|
||||||
|
## ``true``.
|
||||||
##
|
##
|
||||||
## Example:
|
## Example:
|
||||||
##
|
##
|
||||||
|
|
@ -649,22 +650,30 @@ iterator splitLines*(s: string): string =
|
||||||
## ""
|
## ""
|
||||||
var first = 0
|
var first = 0
|
||||||
var last = 0
|
var last = 0
|
||||||
|
var eolpos = 0
|
||||||
while true:
|
while true:
|
||||||
while last < s.len and s[last] notin {'\c', '\l'}: inc(last)
|
while last < s.len and s[last] notin {'\c', '\l'}: inc(last)
|
||||||
yield substr(s, first, last-1)
|
|
||||||
# skip newlines:
|
eolpos = last
|
||||||
if last >= s.len: break
|
if last < s.len:
|
||||||
if s[last] == '\l': inc(last)
|
if s[last] == '\l': inc(last)
|
||||||
elif s[last] == '\c':
|
elif s[last] == '\c':
|
||||||
inc(last)
|
inc(last)
|
||||||
if last < s.len and s[last] == '\l': inc(last)
|
if last < s.len and s[last] == '\l': inc(last)
|
||||||
|
|
||||||
|
yield substr(s, first, if keepEol: last-1 else: eolpos-1)
|
||||||
|
|
||||||
|
# no eol characters consumed means that the string is over
|
||||||
|
if eolpos == last:
|
||||||
|
break
|
||||||
|
|
||||||
first = last
|
first = last
|
||||||
|
|
||||||
proc splitLines*(s: string): seq[string] {.noSideEffect,
|
proc splitLines*(s: string, keepEol = false): seq[string] {.noSideEffect,
|
||||||
rtl, extern: "nsuSplitLines".} =
|
rtl, extern: "nsuSplitLines".} =
|
||||||
## The same as the `splitLines <#splitLines.i,string>`_ iterator, but is a
|
## The same as the `splitLines <#splitLines.i,string>`_ iterator, but is a
|
||||||
## proc that returns a sequence of substrings.
|
## proc that returns a sequence of substrings.
|
||||||
accumulateResult(splitLines(s))
|
accumulateResult(splitLines(s, keepEol=keepEol))
|
||||||
|
|
||||||
proc countLines*(s: string): int {.noSideEffect,
|
proc countLines*(s: string): int {.noSideEffect,
|
||||||
rtl, extern: "nsuCountLines".} =
|
rtl, extern: "nsuCountLines".} =
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,12 @@ proc testRFind =
|
||||||
assert "0123456789ABCDEFGAH".rfind({'A'..'C'}, 13) == 12
|
assert "0123456789ABCDEFGAH".rfind({'A'..'C'}, 13) == 12
|
||||||
assert "0123456789ABCDEFGAH".rfind({'G'..'H'}, 13) == -1
|
assert "0123456789ABCDEFGAH".rfind({'G'..'H'}, 13) == -1
|
||||||
|
|
||||||
|
proc testSplitLines() =
|
||||||
|
let fixture = "a\nb\rc\r\nd"
|
||||||
|
assert len(fixture.splitLines) == 4
|
||||||
|
assert splitLines(fixture) == @["a", "b", "c", "d"]
|
||||||
|
assert splitLines(fixture, keepEol=true) == @["a\n", "b\r", "c\r\n", "d"]
|
||||||
|
|
||||||
proc testCountLines =
|
proc testCountLines =
|
||||||
proc assertCountLines(s: string) = assert s.countLines == s.splitLines.len
|
proc assertCountLines(s: string) = assert s.countLines == s.splitLines.len
|
||||||
assertCountLines("")
|
assertCountLines("")
|
||||||
|
|
@ -252,6 +258,7 @@ proc testParseInts =
|
||||||
testDelete()
|
testDelete()
|
||||||
testFind()
|
testFind()
|
||||||
testRFind()
|
testRFind()
|
||||||
|
testSplitLines()
|
||||||
testCountLines()
|
testCountLines()
|
||||||
testParseInts()
|
testParseInts()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue