# Regex match variables After every successful pattern match, Perl populates a fixed set of variables with information about *what* matched and *where*. These are read-only — you observe them, you do not write to them. The «successful» qualification is critical: an unsuccessful match leaves the variables holding *whatever the previous successful match in the same dynamic scope set them to*. Always gate your access with the boolean result of the match itself. | Variable | Holds | |-----------------|-----------------------------------------------------| | `$1`..`$N` | Text captured by the *N*th capturing group | | `$&` | The entire matched substring | | `$`` | The string preceding the match | | `$'` | The string following the match | | `$+` | Text captured by the highest-numbered group | | `$^N` | Text captured by the *most recently closed* group | | `@-` | Start offsets: `$-[0]` = match, `$-[N]` = $N start | | `@+` | End offsets: `$+[0]` = match end, `$+[N]` = $N end | | `%+` | Hash of named captures: `$+{name}` = `(?...)` | | `%-` | Hash of *all* captures by name (arrayref values) | | `@{^CAPTURE}` | Array of captures: `${^CAPTURE}[0]` = `$1`, etc. | | `${^MATCH}` | Same as `$&`, populated only with the `/p` flag | | `${^PREMATCH}` | Same as `$``, only with `/p` | | `${^POSTMATCH}` | Same as `$'`, only with `/p` | ## The basic pattern ```perl if ("Mr. Smith, age 47" =~ /(\w+)\s+(\w+),\s+age\s+(\d+)/) { print "title: $1\n"; # Mr print "name: $2\n"; # Smith print "age: $3\n"; # 47 print "match: $&\n"; # the full match } ``` The `if` is what makes the access safe. Without it, on a *non-matching* string, `$1`/`$&` would still hold values from some earlier successful match — there is no «match failed → clear» rule. ## Numbered captures — `$1`..`$N` Each `(...)` capturing group fills one variable. The numbering is left-to-right by *opening* parenthesis: ```perl "alpha-beta=42" =~ /^(\w+)-(\w+)=(\d+)$/; print "$1 / $2 / $3\n"; # alpha / beta / 42 ``` Non-capturing groups `(?:...)` and lookarounds `(?=...)`/`(?!...)` do **not** consume a number; they are invisible to the count. For `s///` substitutions, `$1`..`$N` are visible inside the replacement (along with the substitution-only `$1`-style backreferences in single-quoted replacements): ```perl my $s = "John Smith"; $s =~ s/(\w+)\s+(\w+)/$2, $1/; # "Smith, John" ``` ## Named captures — `(?...)` and `%+` Named captures are clearer than counting parentheses, especially in patterns with many groups: ```perl my $log = "2024-03-15 14:32:01 ERROR connection refused"; if ($log =~ /^(?\d{4}-\d{2}-\d{2}) \s+ (?