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 |
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") |