Implement foundation for named captures
This commit is contained in:
parent
bfba4b9983
commit
00b047a660
2 changed files with 39 additions and 1 deletions
33
src/nre.nim
33
src/nre.nim
|
|
@ -2,7 +2,7 @@ import private.pcre as pcre
|
||||||
import private.util
|
import private.util
|
||||||
import tables
|
import tables
|
||||||
import unsigned
|
import unsigned
|
||||||
from strutils import toLower
|
from strutils import toLower, `%`
|
||||||
|
|
||||||
# PCRE Options {{{
|
# PCRE Options {{{
|
||||||
|
|
||||||
|
|
@ -100,3 +100,34 @@ proc initRegex*(pattern: string, options = "Sx"): Regex =
|
||||||
result.pcreExtra = pcre.study(result.pcreObj, 0x0, addr errorMsg)
|
result.pcreExtra = pcre.study(result.pcreObj, 0x0, addr errorMsg)
|
||||||
if result.pcreExtra == nil:
|
if result.pcreExtra == nil:
|
||||||
raise StudyError(msg: $errorMsg)
|
raise StudyError(msg: $errorMsg)
|
||||||
|
|
||||||
|
proc getinfo[T](self: Regex, opt: cint): T =
|
||||||
|
let retcode = pcre.fullinfo(self.pcreObj, self.pcreExtra, opt, addr result)
|
||||||
|
|
||||||
|
if retcode < 0:
|
||||||
|
raise newException(FieldError, "Invalid getinfo for $1, errno $2" % [$opt, $retcode])
|
||||||
|
|
||||||
|
proc getCaptureCount(self: Regex): int =
|
||||||
|
# get the maximum number of captures
|
||||||
|
return getinfo[int](self, pcre.INFO_CAPTURECOUNT)
|
||||||
|
|
||||||
|
type UncheckedArray {.unchecked.}[T] = array[0 .. 0, T]
|
||||||
|
proc getNameToNumberTable(self: Regex): Table[string, int] =
|
||||||
|
let entryCount = getinfo[cint](self, pcre.INFO_NAMECOUNT)
|
||||||
|
let entrySize = getinfo[cint](self, pcre.INFO_NAMEENTRYSIZE)
|
||||||
|
let table = cast[ptr UncheckedArray[uint8]](
|
||||||
|
getinfo[int](self, pcre.INFO_NAMETABLE))
|
||||||
|
|
||||||
|
result = initTable[string, int]()
|
||||||
|
|
||||||
|
for i in 0 .. <entryCount:
|
||||||
|
let pos = i * entrySize
|
||||||
|
let num = (int(table[pos]) shl 8) or int(table[pos + 1])
|
||||||
|
var name = ""
|
||||||
|
|
||||||
|
var idx = 2
|
||||||
|
while table[pos + idx] != 0:
|
||||||
|
name.add(char(table[pos + idx]))
|
||||||
|
idx += 1
|
||||||
|
|
||||||
|
result[name] = num
|
||||||
|
|
|
||||||
7
test/captures.nim
Normal file
7
test/captures.nim
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import unittest
|
||||||
|
include nre
|
||||||
|
|
||||||
|
suite "captures":
|
||||||
|
test "map capture names to numbers":
|
||||||
|
check(getNameToNumberTable(initRegex("(?<v1>1(?<v2>2(?<v3>3))(?'v4'4))()")) ==
|
||||||
|
{ "v1" : 1, "v2" : 2, "v3" : 3, "v4" : 4 }.toTable())
|
||||||
Loading…
Add table
Add a link
Reference in a new issue