From 78423dbdfaffbd2d1dc48131fffea88ecc982bc3 Mon Sep 17 00:00:00 2001 From: flywind Date: Sun, 28 Mar 2021 11:38:00 +0800 Subject: [PATCH] fix #9437 --- lib/impure/re.nim | 18 +++++++++++------- tests/stdlib/tre.nim | 9 ++++++--- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/lib/impure/re.nim b/lib/impure/re.nim index 0c96876b914b4..0c689d67fcf9c 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -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 @@ -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)) diff --git a/tests/stdlib/tre.nim b/tests/stdlib/tre.nim index ea1b5af32cc3b..2857c6c9e5875 100644 --- a/tests/stdlib/tre.nim +++ b/tests/stdlib/tre.nim @@ -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()