Implement toTable(Captures), toSeq(Captures)

This commit is contained in:
Flaviu Tamas
2015-01-10 19:10:43 -05:00
parent cc33942d89
commit 0f4b142c75
2 changed files with 54 additions and 0 deletions

View File

@@ -2,6 +2,7 @@ import private.pcre as pcre
import private.util
import tables
import unsigned
from future import lc, `[]`
from strutils import toLower, `%`
from math import ceil
import optional_t
@@ -102,6 +103,40 @@ proc `[]`*(self: Captures, name: string): string =
## Will fail with KeyError if `name` is not a real named capture
let self = RegexMatch(self)
return self.captures[self.pattern.captureNameToId.fget(name)]
template asTableImpl(cond: bool): stmt {.immediate, dirty.} =
for key in RegexMatch(self).pattern.captureNames:
let nextVal = self[key]
if cond:
result[key] = default
else:
result[key] = nextVal
proc asTable*(self: Captures, default: string = nil): Table[string, string] =
## Gets all the named captures and returns them
result = initTable[string, string]()
asTableImpl(nextVal == nil)
proc asTable*(self: CaptureBounds, default = None[Slice[int]]()):
Table[string, Option[Slice[int]]] =
## Gets all the named captures and returns them
result = initTable[string, Option[Slice[int]]]()
asTableImpl(nextVal.isNone)
template asSeqImpl(cond: bool): stmt {.immediate, dirty.} =
result = @[]
for i in 0 .. <RegexMatch(self).pattern.captureCount:
let nextVal = self[i]
if cond:
result.add(default)
else:
result.add(nextVal)
proc asSeq*(self: CaptureBounds, default = None[Slice[int]]()): seq[Option[Slice[int]]] =
asSeqImpl(nextVal.isNone)
proc asSeq*(self: Captures, default: string = nil): seq[string] =
asSeqImpl(nextVal == nil)
# }}}
# Creation & Destruction {{{

View File

@@ -39,3 +39,22 @@ suite "captures":
check(ex1.captureCount == 2)
# Don't have sets, do this :<
check(ex1.captureNames == @["foo", "bar"] or ex1.captureNames == @["bar", "foo"])
test "named capture table":
let ex1 = initRegex("(?<foo>foo)(?<bar>bar)?").exec("foo").get
check(ex1.captures.asTable == {"foo" : "foo", "bar" : nil}.toTable())
check(ex1.captureBounds.asTable == {"foo" : Some(0..3), "bar" : None[Slice[int]]()}.toTable())
check(ex1.captures.asTable("") == {"foo" : "foo", "bar" : ""}.toTable())
let ex2 = initRegex("(?<foo>foo)(?<bar>bar)?").exec("foobar").get
check(ex2.captures.asTable == {"foo" : "foo", "bar" : "bar"}.toTable())
test "capture sequence":
let ex1 = initRegex("(?<foo>foo)(?<bar>bar)?").exec("foo").get
check(ex1.captures.asSeq == @["foo", nil])
check(ex1.captureBounds.asSeq == @[Some(0..3), None[Slice[int]]()])
check(ex1.captures.asSeq("") == @["foo", ""])
let ex2 = initRegex("(?<foo>foo)(?<bar>bar)?").exec("foobar").get
check(ex2.captures.asSeq == @["foo", "bar"])