Improve replacement performance

This commit is contained in:
Flaviu Tamas
2015-01-19 08:26:32 -05:00
parent e91dd1d956
commit 31dfa97e3d
2 changed files with 49 additions and 1 deletions

View File

@@ -443,7 +443,8 @@ proc replace*(str: string, pattern: Regex,
proc replace*(str: string, pattern: Regex, sub: string): string =
return str.replace(pattern, proc (match: RegexMatch): string =
sub % match.captures.toSeq )
# - 1 because the string numbers are 0-indexed
formatStr(sub, match.captures[name], match.captures[id - 1]) )
# }}}

View File

@@ -5,3 +5,50 @@ proc fget*[K, V](self: Table[K, V], key: K): V =
return self[key]
else:
raise newException(KeyError, "Key does not exist in table: " & $key)
const Ident = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'}
const StartIdent = Ident - {'0'..'9'}
template formatStr*(howExpr, namegetter, idgetter: expr): expr =
let how = howExpr
result = newStringOfCap(how.len)
var i = 0
var lastNum = 1
while i < how.len:
if how[i] != '$':
result.add(how[i])
i += 1
elif how[i + 1] == '$':
result.add('$')
i += 2
elif how[i + 1] == '#':
var id {.inject.} = lastNum
result.add(idgetter)
lastNum += 1
i += 2
elif how[i + 1] in {'0'..'9'}:
i += 1
var id {.inject.} = 0
while i < how.len and how[i] in {'0'..'9'}:
id += (id * 10) + (ord(how[i]) - ord('0'))
i += 1
result.add(idgetter)
lastNum = id + 1
elif how[i + 1] in StartIdent:
i += 1
var name {.inject.} = ""
while i < how.len and how[i] in Ident:
name.add(how[i])
i += 1
result.add(namegetter)
elif how[i + 1] == '{':
i += 2
var name {.inject.} = ""
while i < how.len and how[i] != '}':
name.add(how[i])
i += 1
i += 1
result.add(namegetter)
else:
raise newException(Exception, "Syntax error in format string at " & $i)