Regexp Match in Loop

ID

go.loop_regexp_match

Severity

low

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Efficiency

Language

Go

Tags

code-style, efficiency

Description

Reports a call to one of the regexp package-level convenience functions — regexp.Match, regexp.MatchString or regexp.MatchReader — inside a loop body.

Rationale

Each of these functions parses and compiles the pattern on every call. Invoked once per iteration they recompile the same regular expression repeatedly, and that compilation usually dominates the loop’s cost. Compiling the pattern once with regexp.MustCompile (or regexp.Compile) before the loop and calling the method on the resulting *regexp.Regexp removes the redundant work. A method call on an already-compiled value (re.MatchString(…​)) is not reported.

for _, line := range lines {
    regexp.MatchString("[0-9]+", line) // FLAW — recompiles every iteration
}

re := regexp.MustCompile("[0-9]+")
for _, line := range lines {
    re.MatchString(line) // OK — compiled once, reused
}

Remediation

Hoist the pattern out of the loop with regexp.MustCompile/regexp.Compile and call MatchString/Match/MatchReader on the compiled value inside the loop.