mirror of
https://github.com/nim-lang/Nim.git
synced 2026-05-23 05:09:54 +00:00
Make replace a template
Also required me to fix a name conflict with the format template
This commit is contained in:
21
src/nre.nim
21
src/nre.nim
@@ -423,25 +423,32 @@ proc split*(str: string, pattern: Regex, maxSplit = -1): seq[string] =
|
||||
# This handles "2"
|
||||
result.add(str.substr(bounds.b, str.len - 1))
|
||||
|
||||
proc replace*(str: string, pattern: Regex,
|
||||
subproc: proc (match: RegexMatch): string): string =
|
||||
template replaceImpl(str: string, pattern: Regex,
|
||||
replacement: expr): stmt {.immediate, dirty.} =
|
||||
# XXX seems very similar to split, maybe I can reduce code duplication
|
||||
# somehow?
|
||||
result = ""
|
||||
var lastIdx = 0
|
||||
for match in str.findIter(pattern):
|
||||
for match {.inject.} in str.findIter(pattern):
|
||||
let bounds = match.matchBounds
|
||||
result.add(str.substr(lastIdx, bounds.a - 1))
|
||||
result.add(subproc(match))
|
||||
let nextVal = replacement
|
||||
assert(nextVal != nil)
|
||||
result.add(nextVal)
|
||||
|
||||
lastIdx = bounds.b
|
||||
|
||||
result.add(str.substr(lastIdx, str.len - 1))
|
||||
return result
|
||||
|
||||
proc replace*(str: string, pattern: Regex,
|
||||
subproc: proc (match: RegexMatch): string): string =
|
||||
replaceImpl(str, pattern, subproc(match))
|
||||
|
||||
proc replace*(str: string, pattern: Regex, sub: string): string =
|
||||
return str.replace(pattern, proc (match: RegexMatch): string =
|
||||
# - 1 because the string numbers are 0-indexed
|
||||
formatStr(sub, match.captures[name], match.captures[id - 1]) )
|
||||
# - 1 because the string numbers are 0-indexed
|
||||
replaceImpl(str, pattern,
|
||||
formatStr(sub, match.captures[name], match.captures[id - 1]))
|
||||
|
||||
# }}}
|
||||
|
||||
|
||||
@@ -11,20 +11,20 @@ const StartIdent = Ident - {'0'..'9'}
|
||||
|
||||
template formatStr*(howExpr, namegetter, idgetter: expr): expr =
|
||||
let how = howExpr
|
||||
result = newStringOfCap(how.len)
|
||||
var val = newStringOfCap(how.len)
|
||||
var i = 0
|
||||
var lastNum = 1
|
||||
|
||||
while i < how.len:
|
||||
if how[i] != '$':
|
||||
result.add(how[i])
|
||||
val.add(how[i])
|
||||
i += 1
|
||||
elif how[i + 1] == '$':
|
||||
result.add('$')
|
||||
val.add('$')
|
||||
i += 2
|
||||
elif how[i + 1] == '#':
|
||||
var id {.inject.} = lastNum
|
||||
result.add(idgetter)
|
||||
val.add(idgetter)
|
||||
lastNum += 1
|
||||
i += 2
|
||||
elif how[i + 1] in {'0'..'9'}:
|
||||
@@ -33,7 +33,7 @@ template formatStr*(howExpr, namegetter, idgetter: expr): expr =
|
||||
while i < how.len and how[i] in {'0'..'9'}:
|
||||
id += (id * 10) + (ord(how[i]) - ord('0'))
|
||||
i += 1
|
||||
result.add(idgetter)
|
||||
val.add(idgetter)
|
||||
lastNum = id + 1
|
||||
elif how[i + 1] in StartIdent:
|
||||
i += 1
|
||||
@@ -41,7 +41,7 @@ template formatStr*(howExpr, namegetter, idgetter: expr): expr =
|
||||
while i < how.len and how[i] in Ident:
|
||||
name.add(how[i])
|
||||
i += 1
|
||||
result.add(namegetter)
|
||||
val.add(namegetter)
|
||||
elif how[i + 1] == '{':
|
||||
i += 2
|
||||
var name {.inject.} = ""
|
||||
@@ -49,6 +49,7 @@ template formatStr*(howExpr, namegetter, idgetter: expr): expr =
|
||||
name.add(how[i])
|
||||
i += 1
|
||||
i += 1
|
||||
result.add(namegetter)
|
||||
val.add(namegetter)
|
||||
else:
|
||||
raise newException(Exception, "Syntax error in format string at " & $i)
|
||||
val
|
||||
|
||||
Reference in New Issue
Block a user