Fix up regex.go
This commit is contained in:
@@ -9,75 +9,9 @@ import (
|
|||||||
lua "github.com/yuin/gopher-lua"
|
lua "github.com/yuin/gopher-lua"
|
||||||
|
|
||||||
"modify/logger"
|
"modify/logger"
|
||||||
|
"modify/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegexProcessor implements the Processor interface using regex patterns
|
|
||||||
type RegexProcessor struct{}
|
|
||||||
|
|
||||||
// ToLua sets capture groups as Lua variables (v1, v2, etc. for numeric values and s1, s2, etc. for strings)
|
|
||||||
func (p *RegexProcessor) ToLua(L *lua.LState, data interface{}) error {
|
|
||||||
captureGroups, ok := data.([]*CaptureGroup)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("expected []*CaptureGroup for captures, got %T", data)
|
|
||||||
}
|
|
||||||
|
|
||||||
groupindex := 0
|
|
||||||
for _, capture := range captureGroups {
|
|
||||||
if capture.Name == "" {
|
|
||||||
// We don't want to change the name of the capture group
|
|
||||||
// Even if it's empty
|
|
||||||
tempName := fmt.Sprintf("%d", groupindex+1)
|
|
||||||
groupindex++
|
|
||||||
|
|
||||||
L.SetGlobal("s"+tempName, lua.LString(capture.Value))
|
|
||||||
|
|
||||||
val, err := strconv.ParseFloat(capture.Value, 64)
|
|
||||||
if err == nil {
|
|
||||||
L.SetGlobal("v"+tempName, lua.LNumber(val))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
val, err := strconv.ParseFloat(capture.Value, 64)
|
|
||||||
if err == nil {
|
|
||||||
L.SetGlobal(capture.Name, lua.LNumber(val))
|
|
||||||
} else {
|
|
||||||
L.SetGlobal(capture.Name, lua.LString(capture.Value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// FromLua implements the Processor interface for RegexProcessor
|
|
||||||
func (p *RegexProcessor) FromLuaCustom(L *lua.LState, captureGroups []*CaptureGroup) ([]*CaptureGroup, error) {
|
|
||||||
captureIndex := 0
|
|
||||||
for _, capture := range captureGroups {
|
|
||||||
if capture.Name == "" {
|
|
||||||
capture.Name = fmt.Sprintf("%d", captureIndex+1)
|
|
||||||
|
|
||||||
vVarName := fmt.Sprintf("v%s", capture.Name)
|
|
||||||
sVarName := fmt.Sprintf("s%s", capture.Name)
|
|
||||||
captureIndex++
|
|
||||||
|
|
||||||
vLuaVal := L.GetGlobal(vVarName)
|
|
||||||
sLuaVal := L.GetGlobal(sVarName)
|
|
||||||
|
|
||||||
if sLuaVal.Type() == lua.LTString {
|
|
||||||
capture.Updated = sLuaVal.String()
|
|
||||||
}
|
|
||||||
// Numbers have priority
|
|
||||||
if vLuaVal.Type() == lua.LTNumber {
|
|
||||||
capture.Updated = vLuaVal.String()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Easy shit
|
|
||||||
capture.Updated = L.GetGlobal(capture.Name).String()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return captureGroups, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type CaptureGroup struct {
|
type CaptureGroup struct {
|
||||||
Name string
|
Name string
|
||||||
Value string
|
Value string
|
||||||
@@ -86,8 +20,10 @@ type CaptureGroup struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ProcessContent applies regex replacement with Lua processing
|
// ProcessContent applies regex replacement with Lua processing
|
||||||
func (p *RegexProcessor) ProcessContent(content string, pattern string, luaExpr string) (string, int, int, error) {
|
func ProcessRegex(content string, command utils.ModifyCommand) (string, int, int, error) {
|
||||||
pattern = ResolveRegexPlaceholders(pattern)
|
// We don't HAVE to do this multiple times for a pattern
|
||||||
|
// But it's quick enough for us to not care
|
||||||
|
pattern := resolveRegexPlaceholders(command.Pattern)
|
||||||
logger.Debug("Compiling regex pattern: %s", pattern)
|
logger.Debug("Compiling regex pattern: %s", pattern)
|
||||||
compiledPattern, err := regexp.Compile(pattern)
|
compiledPattern, err := regexp.Compile(pattern)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -96,8 +32,11 @@ func (p *RegexProcessor) ProcessContent(content string, pattern string, luaExpr
|
|||||||
}
|
}
|
||||||
logger.Debug("Compiled pattern successfully: %s", pattern)
|
logger.Debug("Compiled pattern successfully: %s", pattern)
|
||||||
|
|
||||||
previous := luaExpr
|
// Same here, it's just string concatenation, it won't kill us
|
||||||
luaExpr = BuildLuaScript(luaExpr)
|
// More important is that we don't fuck up the command
|
||||||
|
// But we shouldn't be able to since it's passed by value
|
||||||
|
previous := command.LuaExpr
|
||||||
|
luaExpr := BuildLuaScript(command.LuaExpr)
|
||||||
logger.Debug("Transformed Lua expression: %q → %q", previous, luaExpr)
|
logger.Debug("Transformed Lua expression: %q → %q", previous, luaExpr)
|
||||||
|
|
||||||
// Initialize Lua environment
|
// Initialize Lua environment
|
||||||
@@ -199,7 +138,7 @@ func (p *RegexProcessor) ProcessContent(content string, pattern string, luaExpr
|
|||||||
|
|
||||||
captureGroups = deduplicateGroups(captureGroups)
|
captureGroups = deduplicateGroups(captureGroups)
|
||||||
|
|
||||||
if err := p.ToLua(L, captureGroups); err != nil {
|
if err := toLua(L, captureGroups); err != nil {
|
||||||
logger.Error("Failed to set Lua variables: %v", err)
|
logger.Error("Failed to set Lua variables: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -213,7 +152,7 @@ func (p *RegexProcessor) ProcessContent(content string, pattern string, luaExpr
|
|||||||
logger.Trace("Lua script executed successfully")
|
logger.Trace("Lua script executed successfully")
|
||||||
|
|
||||||
// Get modifications from Lua
|
// Get modifications from Lua
|
||||||
captureGroups, err = p.FromLuaCustom(L, captureGroups)
|
captureGroups, err = fromLua(L, captureGroups)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("Failed to retrieve modifications from Lua: %v", err)
|
logger.Error("Failed to retrieve modifications from Lua: %v", err)
|
||||||
continue
|
continue
|
||||||
@@ -314,7 +253,7 @@ func deduplicateGroups(captureGroups []*CaptureGroup) []*CaptureGroup {
|
|||||||
// If it were not here our !num in a named capture group would
|
// If it were not here our !num in a named capture group would
|
||||||
// Expand to another capture group in the capture group
|
// Expand to another capture group in the capture group
|
||||||
// We really only want one (our named) capture group
|
// We really only want one (our named) capture group
|
||||||
func ResolveRegexPlaceholders(pattern string) string {
|
func resolveRegexPlaceholders(pattern string) string {
|
||||||
// Handle special pattern modifications
|
// Handle special pattern modifications
|
||||||
if !strings.HasPrefix(pattern, "(?s)") {
|
if !strings.HasPrefix(pattern, "(?s)") {
|
||||||
pattern = "(?s)" + pattern
|
pattern = "(?s)" + pattern
|
||||||
@@ -348,3 +287,67 @@ func ResolveRegexPlaceholders(pattern string) string {
|
|||||||
})
|
})
|
||||||
return pattern
|
return pattern
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToLua sets capture groups as Lua variables (v1, v2, etc. for numeric values and s1, s2, etc. for strings)
|
||||||
|
func toLua(L *lua.LState, data interface{}) error {
|
||||||
|
captureGroups, ok := data.([]*CaptureGroup)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("expected []*CaptureGroup for captures, got %T", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
groupindex := 0
|
||||||
|
for _, capture := range captureGroups {
|
||||||
|
if capture.Name == "" {
|
||||||
|
// We don't want to change the name of the capture group
|
||||||
|
// Even if it's empty
|
||||||
|
tempName := fmt.Sprintf("%d", groupindex+1)
|
||||||
|
groupindex++
|
||||||
|
|
||||||
|
L.SetGlobal("s"+tempName, lua.LString(capture.Value))
|
||||||
|
|
||||||
|
val, err := strconv.ParseFloat(capture.Value, 64)
|
||||||
|
if err == nil {
|
||||||
|
L.SetGlobal("v"+tempName, lua.LNumber(val))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val, err := strconv.ParseFloat(capture.Value, 64)
|
||||||
|
if err == nil {
|
||||||
|
L.SetGlobal(capture.Name, lua.LNumber(val))
|
||||||
|
} else {
|
||||||
|
L.SetGlobal(capture.Name, lua.LString(capture.Value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromLua implements the Processor interface for RegexProcessor
|
||||||
|
func fromLua(L *lua.LState, captureGroups []*CaptureGroup) ([]*CaptureGroup, error) {
|
||||||
|
captureIndex := 0
|
||||||
|
for _, capture := range captureGroups {
|
||||||
|
if capture.Name == "" {
|
||||||
|
capture.Name = fmt.Sprintf("%d", captureIndex+1)
|
||||||
|
|
||||||
|
vVarName := fmt.Sprintf("v%s", capture.Name)
|
||||||
|
sVarName := fmt.Sprintf("s%s", capture.Name)
|
||||||
|
captureIndex++
|
||||||
|
|
||||||
|
vLuaVal := L.GetGlobal(vVarName)
|
||||||
|
sLuaVal := L.GetGlobal(sVarName)
|
||||||
|
|
||||||
|
if sLuaVal.Type() == lua.LTString {
|
||||||
|
capture.Updated = sLuaVal.String()
|
||||||
|
}
|
||||||
|
// Numbers have priority
|
||||||
|
if vLuaVal.Type() == lua.LTNumber {
|
||||||
|
capture.Updated = vLuaVal.String()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Easy shit
|
||||||
|
capture.Updated = L.GetGlobal(capture.Name).String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return captureGroups, nil
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user