From 31dfa97e3d55f68f468c12a2357eb16e8502da25 Mon Sep 17 00:00:00 2001 From: Flaviu Tamas Date: Mon, 19 Jan 2015 08:26:32 -0500 Subject: [PATCH] Improve replacement performance --- src/nre.nim | 3 ++- src/private/util.nim | 47 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/nre.nim b/src/nre.nim index 2874d66b42..ffa4a6a6ec 100644 --- a/src/nre.nim +++ b/src/nre.nim @@ -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]) ) # }}} diff --git a/src/private/util.nim b/src/private/util.nim index afd90a4852..5629e81e61 100644 --- a/src/private/util.nim +++ b/src/private/util.nim @@ -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)