Make replace a template
Also required me to fix a name conflict with the format template
This commit is contained in:
parent
a5693675fb
commit
f34a7dc1f5
2 changed files with 22 additions and 14 deletions
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"
|
# This handles "2"
|
||||||
result.add(str.substr(bounds.b, str.len - 1))
|
result.add(str.substr(bounds.b, str.len - 1))
|
||||||
|
|
||||||
proc replace*(str: string, pattern: Regex,
|
template replaceImpl(str: string, pattern: Regex,
|
||||||
subproc: proc (match: RegexMatch): string): string =
|
replacement: expr): stmt {.immediate, dirty.} =
|
||||||
# XXX seems very similar to split, maybe I can reduce code duplication
|
# XXX seems very similar to split, maybe I can reduce code duplication
|
||||||
# somehow?
|
# somehow?
|
||||||
result = ""
|
result = ""
|
||||||
var lastIdx = 0
|
var lastIdx = 0
|
||||||
for match in str.findIter(pattern):
|
for match {.inject.} in str.findIter(pattern):
|
||||||
let bounds = match.matchBounds
|
let bounds = match.matchBounds
|
||||||
result.add(str.substr(lastIdx, bounds.a - 1))
|
result.add(str.substr(lastIdx, bounds.a - 1))
|
||||||
result.add(subproc(match))
|
let nextVal = replacement
|
||||||
|
assert(nextVal != nil)
|
||||||
|
result.add(nextVal)
|
||||||
|
|
||||||
lastIdx = bounds.b
|
lastIdx = bounds.b
|
||||||
|
|
||||||
result.add(str.substr(lastIdx, str.len - 1))
|
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 =
|
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
|
||||||
# - 1 because the string numbers are 0-indexed
|
replaceImpl(str, pattern,
|
||||||
formatStr(sub, match.captures[name], match.captures[id - 1]) )
|
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 =
|
template formatStr*(howExpr, namegetter, idgetter: expr): expr =
|
||||||
let how = howExpr
|
let how = howExpr
|
||||||
result = newStringOfCap(how.len)
|
var val = newStringOfCap(how.len)
|
||||||
var i = 0
|
var i = 0
|
||||||
var lastNum = 1
|
var lastNum = 1
|
||||||
|
|
||||||
while i < how.len:
|
while i < how.len:
|
||||||
if how[i] != '$':
|
if how[i] != '$':
|
||||||
result.add(how[i])
|
val.add(how[i])
|
||||||
i += 1
|
i += 1
|
||||||
elif how[i + 1] == '$':
|
elif how[i + 1] == '$':
|
||||||
result.add('$')
|
val.add('$')
|
||||||
i += 2
|
i += 2
|
||||||
elif how[i + 1] == '#':
|
elif how[i + 1] == '#':
|
||||||
var id {.inject.} = lastNum
|
var id {.inject.} = lastNum
|
||||||
result.add(idgetter)
|
val.add(idgetter)
|
||||||
lastNum += 1
|
lastNum += 1
|
||||||
i += 2
|
i += 2
|
||||||
elif how[i + 1] in {'0'..'9'}:
|
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'}:
|
while i < how.len and how[i] in {'0'..'9'}:
|
||||||
id += (id * 10) + (ord(how[i]) - ord('0'))
|
id += (id * 10) + (ord(how[i]) - ord('0'))
|
||||||
i += 1
|
i += 1
|
||||||
result.add(idgetter)
|
val.add(idgetter)
|
||||||
lastNum = id + 1
|
lastNum = id + 1
|
||||||
elif how[i + 1] in StartIdent:
|
elif how[i + 1] in StartIdent:
|
||||||
i += 1
|
i += 1
|
||||||
|
|
@ -41,7 +41,7 @@ template formatStr*(howExpr, namegetter, idgetter: expr): expr =
|
||||||
while i < how.len and how[i] in Ident:
|
while i < how.len and how[i] in Ident:
|
||||||
name.add(how[i])
|
name.add(how[i])
|
||||||
i += 1
|
i += 1
|
||||||
result.add(namegetter)
|
val.add(namegetter)
|
||||||
elif how[i + 1] == '{':
|
elif how[i + 1] == '{':
|
||||||
i += 2
|
i += 2
|
||||||
var name {.inject.} = ""
|
var name {.inject.} = ""
|
||||||
|
|
@ -49,6 +49,7 @@ template formatStr*(howExpr, namegetter, idgetter: expr): expr =
|
||||||
name.add(how[i])
|
name.add(how[i])
|
||||||
i += 1
|
i += 1
|
||||||
i += 1
|
i += 1
|
||||||
result.add(namegetter)
|
val.add(namegetter)
|
||||||
else:
|
else:
|
||||||
raise newException(Exception, "Syntax error in format string at " & $i)
|
raise newException(Exception, "Syntax error in format string at " & $i)
|
||||||
|
val
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue