mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-16 16:14:20 +00:00
Add replace
Also came a cross a find bug with 0-length subject strings
This commit is contained in:
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 previousMatch: RegexMatch
|
||||
while offset != endpos:
|
||||
if offset > endpos:
|
||||
# eos occurs in the middle of a unicode char? die.
|
||||
raise newException(AssertionError, "Input string has malformed unicode")
|
||||
|
||||
while true:
|
||||
var flags = 0
|
||||
|
||||
if previousMatch != nil and
|
||||
@@ -356,11 +352,16 @@ iterator findIter*(str: string, pattern: Regex, start = 0, endpos = -1): RegexMa
|
||||
elif unicode:
|
||||
# XXX what about invalid unicode?
|
||||
offset += str.runeLenAt(offset)
|
||||
assert(offset <= endpos)
|
||||
else:
|
||||
offset = currentMatch.matchBounds.b
|
||||
|
||||
yield currentMatch
|
||||
|
||||
if offset >= endpos:
|
||||
# do while
|
||||
break
|
||||
|
||||
proc find*(str: string, pattern: Regex, start = 0, endpos = -1): RegexMatch =
|
||||
## Returns a `RegexMatch` if there is a match between `start` and `endpos`, otherwise
|
||||
## it returns nil.
|
||||
@@ -415,3 +416,18 @@ proc split*(str: string, pattern: Regex): seq[string] =
|
||||
# but "1 2".split(/ /) needs to return @["1", "2"].
|
||||
# This handles "2"
|
||||
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":
|
||||
check("222".findAllStr(re"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 split
|
||||
import match
|
||||
import replace
|
||||
|
||||
Reference in New Issue
Block a user