AnP/Go/Utils/Patterns.go

100 lines
3.1 KiB
Go

package Utils
import (
"bytes"
"regexp"
)
type PatternMatch struct {
String string
Groups []string
Span []int
Ok bool
}
type PatternsModel struct {
RE_PARENT_PATH *regexp.Regexp
RE_SLASH *regexp.Regexp
RE_KEY *regexp.Regexp
RE_PASCAL_KEY *regexp.Regexp
RE_STRING_VARIABLES *regexp.Regexp
RE_ROUTE *regexp.Regexp
RE_ROUTES_FORMAT *regexp.Regexp
RE_TRACE_STACK *regexp.Regexp
RE_EXTENSION *regexp.Regexp
RE_VIEWS_STRING_VARIABLES *regexp.Regexp
RE_ATTRIBUTE_BAD_SET_CHARACTERS *regexp.Regexp
RE_SPACES *regexp.Regexp
}
var Patterns PatternsModel = PatternsModel{
RE_PARENT_PATH: regexp.MustCompile(`^(.+)[\/\\][^\/\\]+$`),
RE_SLASH: regexp.MustCompile(`[\/\\]+`),
RE_KEY: regexp.MustCompile(`(?i)^[a-z0-9_]+$`),
RE_PASCAL_KEY: regexp.MustCompile(`(?i)^[a-z0-9_\-]+$`),
RE_STRING_VARIABLES: regexp.MustCompile(`(?i)\{([a-z0-9_]+)\}`),
RE_ROUTE: regexp.MustCompile(`(?i)^(?:([^\:]+)\:)?([^ ]+) +(?:([^ \:]+)\:([^ ]+)|([a-z0-9_]+)|([^ ]+))(?: +(?:\*|([^\s]+))(?: ([^\s]+)))?$`),
RE_ROUTES_FORMAT: regexp.MustCompile(`(?i)\{([a-z0-9_]+)\}|([\\\/\-\{\[\]\}\\(\)\*\^\|\!\?\+\.\:\$])`),
RE_TRACE_STACK: regexp.MustCompile(`[\n\r](([^\.\(\s]+|\..)+)\([^\n\r]+[\r\n]+\s+([^\:\s]+)\:([0-9]+)`),
RE_EXTENSION: regexp.MustCompile(`\.([^\.\/\\]+)$`),
RE_VIEWS_STRING_VARIABLES: regexp.MustCompile(`(?i)\{([a-z0-9_]+)\}|\{2}((?:[a-z0-9_]+|\{[a-z0-9_]+\})+)\}{2}`),
RE_ATTRIBUTE_BAD_SET_CHARACTERS: regexp.MustCompile(`(?i)[^a-z0-9]+`),
RE_SPACES: regexp.MustCompile(` +`),
}
/*
RE_ROUTE: all, method?, route, (method, controller | view | path), permissions?, options?
*/
func (_self *PatternsModel) GetMatches(_string string, groups [][]byte) PatternMatch {
var binary []byte = []byte(_string)
var matches PatternMatch
if groups != nil {
matches.String = _string
matches.Groups = []string{}
matches.Span = []int{bytes.Index(binary, groups[0]), len(groups[0])}
matches.Ok = true
for _, group := range groups {
matches.Groups = append(matches.Groups, string(group))
}
}
return matches
}
func (_self *PatternsModel) Match(_string string, pattern *regexp.Regexp) PatternMatch {
return _self.GetMatches(_string, pattern.FindSubmatch([]byte(_string)))
}
func (_self *PatternsModel) Replace(_string string, pattern *regexp.Regexp, to any) string {
var processed string = ""
var binary []byte = []byte(_string)
for {
var matches PatternMatch = _self.Match(string(binary), pattern)
if !matches.Ok {
break
}
processed += string(binary[:matches.Span[0]])
switch value := to.(type) {
case func(PatternMatch) string:
processed += value(matches)
case string:
processed += value
}
binary = binary[matches.Span[0]+matches.Span[1]:]
}
return processed + string(binary)
}