core/regex.nim
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
import strutils
import ../vendor/sgregex
type
InvalidRegexError = ref SystemError
proc newRegex(pattern, mods: string): ptr srx_Context =
result = srx_Create(pattern, mods)
if result.isNil:
raise(InvalidRegexError(msg: "Invalid regular expression: \"$1\"" % pattern))
proc match*(str, pattern, mods: string): bool =
let r = newRegex(pattern, mods)
result = srx_Match(r, str, 0) == 1
discard srx_Destroy(r)
proc match*(str, pattern: string): bool =
return match(str, pattern, "")
proc search*(str, pattern, mods: string): seq[string] =
let r = newRegex(pattern, mods)
discard srx_Match(r, str, 0) == 1
let count = srx_GetCaptureCount(r)
result = newSeq[string](count)
for i in 0..count-1:
var first = 0
var last = 0
discard srx_GetCaptured(r, i, addr first, addr last)
result[i] = str.substr(first, last-1)
discard srx_Destroy(r)
proc search*(str, pattern: string): seq[string] =
return search(str, pattern, "")
proc replace*(str, pattern, repl, mods: string): string =
var r = newRegex(pattern, mods)
result = $srx_Replace(r, str, repl)
discard srx_Destroy(r)
proc replace*(str, pattern, repl: string): string =
return replace(str, pattern, repl, "")
proc `=~`*(str, r: string): seq[string] =
let m = r.search("(s)?/(.+?)/((.+?)/)?([mis]{0,3})?")
# full match, s, reg, replace/, replace, flags
if m[1] == "s" and m[3] != "":
return @[replace(str, m[2], m[4], m[5])]
else:
return search(str, m[2], m[5])
when isMainModule:
proc tmatch(str, pattern: string) =
echo str, " =~ ", "/", pattern, "/", " -> ", str.match(pattern)
proc tsearch(str, pattern: string) =
echo str, " =~ ", "/", pattern, "/", " -> ", str.search(pattern)
proc tsearch(str, pattern, mods: string) =
echo str, " =~ ", "/", pattern, "/", mods, " -> ", str.search(pattern, mods)
proc treplace(str, pattern, repl: string) =
echo str, " =~ ", "s/", pattern, "/", repl, "/", " -> ", str.replace(pattern, repl)
proc toperator(str, pattern: string) =
echo str, " =~ ", pattern, " -> ", str =~ pattern
"HELLO".tmatch("^H(.*)O$")
"HELLO".tmatch("^H(.*)S$")
"HELLO".tsearch("^H(E)(.*)O$")
"Hello, World!".treplace("[a-zA-Z]+,", "Goodbye,")
"127.0.0.1".tsearch("^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$")
"127.0.0.1".treplace("^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$", "$4.$3.$1.$2")
"127.0.0.1".treplace("[0-9]+", "255")
"Hello".tsearch("HELLO", "i")
"Hello\nWorld!".tsearch("HELLO.WORLD", "mis")
"Testing".toperator("s/test/eat/i")
|