Skip to content

Commit

Permalink
fix #9437
Browse files Browse the repository at this point in the history
  • Loading branch information
ringabout committed Mar 28, 2021
1 parent aa9dc77 commit 78423db
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 10 deletions.
18 changes: 11 additions & 7 deletions lib/impure/re.nim
Original file line number Diff line number Diff line change
Expand Up @@ -200,27 +200,27 @@ proc findBounds*(s: string, pattern: Regex,
result = findBounds(cstring(s), pattern, matches, start, s.len)

proc findBounds*(buf: cstring, pattern: Regex,
start = 0, bufSize: int): tuple[first, last: int] =
start = 0, bufSize = 0, flags = int32(0)): tuple[first, last: int] =
## returns the `first` and `last` position of `pattern` in `buf`,
## where `buf` has length `bufSize` (not necessarily `'\0'` terminated).
## If it does not match, `(-1,0)` is returned.
var
rtarray = initRtArray[cint](3)
rawMatches = rtarray.getRawData
res = pcre.exec(pattern.h, pattern.e, buf, bufSize.cint, start.cint, 0'i32,
res = pcre.exec(pattern.h, pattern.e, buf, bufSize.cint, start.cint, flags,
cast[ptr cint](rawMatches), 3)
if res < 0'i32: return (int(res), 0)
if res < 0'i32: return (-1, 0)
return (int(rawMatches[0]), int(rawMatches[1]-1))

proc findBounds*(s: string, pattern: Regex,
start = 0): tuple[first, last: int] {.inline.} =
start = 0, flags = int32(0)): tuple[first, last: int] {.inline.} =
## returns the `first` and `last` position of `pattern` in `s`.
## If it does not match, `(-1,0)` is returned.
##
## Note: there is a speed improvement if the matches do not need to be captured.
runnableExamples:
assert findBounds("01234abc89", re"abc") == (5,7)
result = findBounds(cstring(s), pattern, start, s.len)
result = findBounds(cstring(s), pattern, start, s.len, flags)

proc matchOrFind(buf: cstring, pattern: Regex, start, bufSize: int, flags: cint): cint =
var
Expand Down Expand Up @@ -433,12 +433,16 @@ proc replace*(s: string, sub: Regex, by = ""): string =
doAssert "var1=key; var2=key2".replace(re"(\w+)=(\w+)", "?") == "?; ?"
result = ""
var prev = 0
var flags = int32(0)
while prev < s.len:
var match = findBounds(s, sub, prev)
var match = findBounds(s, sub, prev, flags)
flags = 0
if match.first < 0: break
add(result, substr(s, prev, match.first-1))
add(result, by)
if match.last + 1 == prev: break
if match.first > match.last:
# 0-len match
flags = pcre.NOTEMPTY_ATSTART
prev = match.last + 1
add(result, substr(s, prev))

Expand Down
9 changes: 6 additions & 3 deletions tests/stdlib/tre.nim
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,13 @@ proc testAll() =
accum.add($x)
doAssert(accum == @["a","b","c"])

block:
# bug #9306
block: # bug #9306
doAssert replace("bar", re"^", "foo") == "foobar"
doAssert replace("foo", re"", "-") == "-foo"
doAssert replace("foo", re"$", "bar") == "foobar"


block: # bug #9437
doAssert replace("foo", re"", "-") == "-f-o-o-"
doAssert replace("ooo", re"o", "-") == "---"

testAll()

0 comments on commit 78423db

Please sign in to comment.