Make replace a template

Also required me to fix a name conflict with the format template
This commit is contained in:
Flaviu Tamas
2015-01-19 15:59:45 -05:00
parent a5693675fb
commit f34a7dc1f5
2 changed files with 22 additions and 14 deletions

View File

@@ -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]))
# }}}

View File

@@ -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