Goal
Introduce an internal regex-based match/replace engine that supports capture groups ($1, $2, ...) in the replacement string, shared by both the content-rewrite and rename code paths.
This is the engine work that the user-facing -e/--regex flag will sit on top of. It can land without exposing the flag — existing literal mode continues to call the engine with the pattern escaped.
Scope
- Use Go's standard
regexp package (RE2 syntax — no catastrophic backtracking, predictable performance).
ReplaceAllString already supports $N and ${name} references; this is mostly plumbing.
- Single shared engine API used by both rename and content paths so the syntax is identical.
- Literal mode delegates to the same engine by escaping the pattern with
regexp.QuoteMeta.
Suggested API shape
type Pattern struct {
re *regexp.Regexp
repl string
}
func Compile(pattern, replacement string, literal bool) (*Pattern, error)
func (p *Pattern) Match(s string) bool
func (p *Pattern) Replace(s string) string
Both the file-content path and the rename path consume *Pattern — no separate logic per mode.
Acceptance
Goal
Introduce an internal regex-based match/replace engine that supports capture groups (
$1,$2, ...) in the replacement string, shared by both the content-rewrite and rename code paths.This is the engine work that the user-facing
-e/--regexflag will sit on top of. It can land without exposing the flag — existing literal mode continues to call the engine with the pattern escaped.Scope
regexppackage (RE2 syntax — no catastrophic backtracking, predictable performance).ReplaceAllStringalready supports$Nand${name}references; this is mostly plumbing.regexp.QuoteMeta.Suggested API shape
Both the file-content path and the rename path consume
*Pattern— no separate logic per mode.Acceptance
regexp.QuoteMeta$$,$0, out-of-range refs)