Add replace
Also came a cross a find bug with 0-length subject strings
This commit is contained in:
parent
a7ce05b42f
commit
4d25a89ba9
4 changed files with 34 additions and 5 deletions
26
src/nre.nim
26
src/nre.nim
|
|
@ -329,11 +329,7 @@ iterator findIter*(str: string, pattern: Regex, start = 0, endpos = -1): RegexMa
|
||||||
|
|
||||||
var offset = start
|
var offset = start
|
||||||
var previousMatch: RegexMatch
|
var previousMatch: RegexMatch
|
||||||
while offset != endpos:
|
while true:
|
||||||
if offset > endpos:
|
|
||||||
# eos occurs in the middle of a unicode char? die.
|
|
||||||
raise newException(AssertionError, "Input string has malformed unicode")
|
|
||||||
|
|
||||||
var flags = 0
|
var flags = 0
|
||||||
|
|
||||||
if previousMatch != nil and
|
if previousMatch != nil and
|
||||||
|
|
@ -356,11 +352,16 @@ iterator findIter*(str: string, pattern: Regex, start = 0, endpos = -1): RegexMa
|
||||||
elif unicode:
|
elif unicode:
|
||||||
# XXX what about invalid unicode?
|
# XXX what about invalid unicode?
|
||||||
offset += str.runeLenAt(offset)
|
offset += str.runeLenAt(offset)
|
||||||
|
assert(offset <= endpos)
|
||||||
else:
|
else:
|
||||||
offset = currentMatch.matchBounds.b
|
offset = currentMatch.matchBounds.b
|
||||||
|
|
||||||
yield currentMatch
|
yield currentMatch
|
||||||
|
|
||||||
|
if offset >= endpos:
|
||||||
|
# do while
|
||||||
|
break
|
||||||
|
|
||||||
proc find*(str: string, pattern: Regex, start = 0, endpos = -1): RegexMatch =
|
proc find*(str: string, pattern: Regex, start = 0, endpos = -1): RegexMatch =
|
||||||
## Returns a `RegexMatch` if there is a match between `start` and `endpos`, otherwise
|
## Returns a `RegexMatch` if there is a match between `start` and `endpos`, otherwise
|
||||||
## it returns nil.
|
## it returns nil.
|
||||||
|
|
@ -415,3 +416,18 @@ proc split*(str: string, pattern: Regex): seq[string] =
|
||||||
# but "1 2".split(/ /) needs to return @["1", "2"].
|
# but "1 2".split(/ /) needs to return @["1", "2"].
|
||||||
# This handles "2"
|
# This handles "2"
|
||||||
result.add(str.substr(lastIdx, str.len - 1))
|
result.add(str.substr(lastIdx, str.len - 1))
|
||||||
|
|
||||||
|
proc replace*(str: string, pattern: Regex,
|
||||||
|
subproc: proc (match: RegexMatch): string): string =
|
||||||
|
# XXX seems very similar to split, maybe I can reduce code duplication
|
||||||
|
# somehow?
|
||||||
|
result = ""
|
||||||
|
var lastIdx = 0
|
||||||
|
for match in str.findIter(pattern):
|
||||||
|
let bounds = match.matchBounds
|
||||||
|
result.add(str.substr(lastIdx, bounds.a - 1))
|
||||||
|
result.add(subproc(match))
|
||||||
|
|
||||||
|
lastIdx = bounds.b
|
||||||
|
|
||||||
|
result.add(str.substr(lastIdx, str.len - 1))
|
||||||
|
|
|
||||||
|
|
@ -16,3 +16,7 @@ suite "find":
|
||||||
test "overlapping find":
|
test "overlapping find":
|
||||||
check("222".findAllStr(re"22") == @["22"])
|
check("222".findAllStr(re"22") == @["22"])
|
||||||
check("2222".findAllStr(re"22") == @["22", "22"])
|
check("2222".findAllStr(re"22") == @["22", "22"])
|
||||||
|
|
||||||
|
test "len 0 find":
|
||||||
|
check("".findAllStr(re"\ ") == newSeq[string]())
|
||||||
|
check("".findAllStr(re"") == @[""])
|
||||||
|
|
|
||||||
8
test/replace.nim
Normal file
8
test/replace.nim
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
include nre
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
suite "replace":
|
||||||
|
test "replace with 0-length strings":
|
||||||
|
check("".replace(re"1", proc (v: RegexMatch): string = "1") == "")
|
||||||
|
check(" ".replace(re"", proc (v: RegexMatch): string = "1") == "1 ")
|
||||||
|
check("".replace(re"", proc (v: RegexMatch): string = "1") == "1")
|
||||||
|
|
@ -4,3 +4,4 @@ import captures
|
||||||
import find
|
import find
|
||||||
import split
|
import split
|
||||||
import match
|
import match
|
||||||
|
import replace
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue