diff --git a/processor/regex.go b/processor/regex.go
index 9dab03a..add4bab 100644
--- a/processor/regex.go
+++ b/processor/regex.go
@@ -80,6 +80,20 @@ func (p *RegexProcessor) ProcessContent(content string, pattern string, luaExpr
log.Printf("Pattern modified to include (?s): %s", pattern)
}
+ // The order of these replaces is important
+ // This one handles !num-s inside of named capture groups
+ // If it were not here our !num in a named capture group would
+ // Expand to another capture group in the capture group
+ // We really only want one (our named) capture group
+ namedGroupNum := regexp.MustCompile(`(?:(\?<[^>]+>)(!num))`)
+ pattern = namedGroupNum.ReplaceAllStringFunc(pattern, func(match string) string {
+ parts := namedGroupNum.FindStringSubmatch(match)
+ if len(parts) != 3 {
+ return match
+ }
+ replacement := `\d*\.?\d+`
+ return parts[1] + replacement
+ })
pattern = strings.ReplaceAll(pattern, "!num", `"?(\d*\.?\d+)"?`)
pattern = strings.ReplaceAll(pattern, "!any", `.*?`)
repPattern := regexp.MustCompile(`!rep\(([^,]+),\s*(\d+)\)`)
@@ -125,7 +139,7 @@ func (p *RegexProcessor) ProcessContent(content string, pattern string, luaExpr
log.Printf("Error creating Lua state: %v", err)
return "", 0, 0, fmt.Errorf("error creating Lua state: %v", err)
}
- // Hmm... Maybe we don't want to defer this..
+ // Hmm... Maybe we don't want to defer this..
// Maybe we want to close them every iteration
// We'll leave it as is for now
defer L.Close()
diff --git a/processor/regex_test.go b/processor/regex_test.go
index e1f3f87..508d5ca 100644
--- a/processor/regex_test.go
+++ b/processor/regex_test.go
@@ -581,6 +581,39 @@ func TestNamedCaptureGroups(t *testing.T) {
}
}
+func TestNamedCaptureGroupsNum(t *testing.T) {
+ content := `
+ -
+ 100
+
+`
+
+ expected := `
+ -
+ 200
+
+`
+
+ p := &RegexProcessor{}
+ result, mods, matches, err := p.ProcessContent(content, `(?s)(?!num)`, "amount = amount * 2")
+
+ if err != nil {
+ t.Fatalf("Error processing content: %v", err)
+ }
+
+ if matches != 1 {
+ t.Errorf("Expected 1 match, got %d", matches)
+ }
+
+ if mods != 1 {
+ t.Errorf("Expected 1 modification, got %d", mods)
+ }
+
+ if result != expected {
+ t.Errorf("Expected content to be:\n%s\n\nGot:\n%s", expected, result)
+ }
+}
+
func TestMultipleNamedCaptureGroups(t *testing.T) {
content := `
Widget