This commit is contained in:
Flaviu Tamas 2018-11-18 20:25:59 -05:00
commit 22b3e9df27
No known key found for this signature in database
GPG key ID: D6BF32C876496756
4 changed files with 16 additions and 12 deletions

View file

@ -289,7 +289,7 @@ proc `[]`*(pattern: Captures, i: int): string =
let bounds = bounds.get let bounds = bounds.get
return pattern.str.substr(bounds.a, bounds.b) return pattern.str.substr(bounds.a, bounds.b)
else: else:
return "" return nil
proc match*(pattern: RegexMatch): string = proc match*(pattern: RegexMatch): string =
return pattern.captures[-1] return pattern.captures[-1]
@ -313,9 +313,9 @@ template toTableImpl(cond: untyped) {.dirty.} =
else: else:
result[key] = nextVal result[key] = nextVal
proc toTable*(pattern: Captures, default: string = ""): Table[string, string] = proc toTable*(pattern: Captures, default: string = nil): Table[string, string] =
result = initTable[string, string]() result = initTable[string, string]()
toTableImpl(nextVal.len == 0) toTableImpl(nextVal == nil)
proc toTable*(pattern: CaptureBounds, default = none(HSlice[int, int])): proc toTable*(pattern: CaptureBounds, default = none(HSlice[int, int])):
Table[string, Option[HSlice[int, int]]] = Table[string, Option[HSlice[int, int]]] =
@ -334,13 +334,13 @@ template itemsImpl(cond: untyped) {.dirty.} =
iterator items*(pattern: CaptureBounds, default = none(HSlice[int, int])): Option[HSlice[int, int]] = iterator items*(pattern: CaptureBounds, default = none(HSlice[int, int])): Option[HSlice[int, int]] =
itemsImpl(nextVal.isNone) itemsImpl(nextVal.isNone)
iterator items*(pattern: Captures, default: string = ""): string = iterator items*(pattern: Captures, default: string = nil): string =
itemsImpl(nextVal.len == 0) itemsImpl(nextVal == nil)
proc toSeq*(pattern: CaptureBounds, default = none(HSlice[int, int])): seq[Option[HSlice[int, int]]] = proc toSeq*(pattern: CaptureBounds, default = none(HSlice[int, int])): seq[Option[HSlice[int, int]]] =
accumulateResult(pattern.items(default)) accumulateResult(pattern.items(default))
proc toSeq*(pattern: Captures, default: string = ""): seq[string] = proc toSeq*(pattern: Captures, default: string = nil): seq[string] =
accumulateResult(pattern.items(default)) accumulateResult(pattern.items(default))
proc `$`*(pattern: RegexMatch): string = proc `$`*(pattern: RegexMatch): string =

View file

@ -10,7 +10,11 @@ proc fget*[K, V](self: Table[K, V], key: K): V =
const Ident = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'} const Ident = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'}
const StartIdent = Ident - {'0'..'9'} const StartIdent = Ident - {'0'..'9'}
template checkNil(arg: string): string = arg proc checkNil(arg: string): string =
if arg == nil:
raise newException(ValueError, "Cannot use nil capture")
else:
return arg
template formatStr*(howExpr, namegetter, idgetter): untyped = template formatStr*(howExpr, namegetter, idgetter): untyped =
let how = howExpr let how = howExpr

View file

@ -27,7 +27,7 @@ suite "captures":
let ex2 = "foo".find(re("(?<foo>foo)(?<bar>bar)?")) let ex2 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
check(ex2.captures["foo"] == "foo") check(ex2.captures["foo"] == "foo")
check(ex2.captures["bar"] == "") check(ex2.captures["bar"] == nil)
test "named capture bounds": test "named capture bounds":
let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?")) let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
@ -41,7 +41,7 @@ suite "captures":
test "named capture table": test "named capture table":
let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?")) let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
check(ex1.captures.toTable == {"foo" : "foo", "bar" : ""}.toTable()) check(ex1.captures.toTable == {"foo" : "foo", "bar" : nil}.toTable())
check(ex1.captureBounds.toTable == {"foo" : some(0..2), "bar" : none(Slice[int])}.toTable()) check(ex1.captureBounds.toTable == {"foo" : some(0..2), "bar" : none(Slice[int])}.toTable())
check(ex1.captures.toTable("") == {"foo" : "foo", "bar" : ""}.toTable()) check(ex1.captures.toTable("") == {"foo" : "foo", "bar" : ""}.toTable())
@ -50,7 +50,7 @@ suite "captures":
test "capture sequence": test "capture sequence":
let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?")) let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
check(ex1.captures.toSeq == @["foo", ""]) check(ex1.captures.toSeq == @["foo", nil])
check(ex1.captureBounds.toSeq == @[some(0..2), none(Slice[int])]) check(ex1.captureBounds.toSeq == @[some(0..2), none(Slice[int])])
check(ex1.captures.toSeq("") == @["foo", ""]) check(ex1.captures.toSeq("") == @["foo", ""])

View file

@ -16,5 +16,5 @@ suite "replace":
check("123".replace(re"(?<foo>\d)(\d)", "${foo}$#$#") == "1123") check("123".replace(re"(?<foo>\d)(\d)", "${foo}$#$#") == "1123")
test "replacing missing captures should throw instead of segfaulting": test "replacing missing captures should throw instead of segfaulting":
discard "ab".replace(re"(a)|(b)", "$1$2") expect ValueError: discard "ab".replace(re"(a)|(b)", "$1$2")
discard "b".replace(re"(a)?(b)", "$1$2") expect ValueError: discard "b".replace(re"(a)?(b)", "$1$2")