How to access captured groups using $1, $2 in Perl?
Question
How to access captured groups using $1, $2 in Perl?
In Perl, when you perform a regular expression match that contains capturing parentheses (...), the matched substrings within those parentheses are stored in special variables $1, $2, $3, and so forth. These variables allow you to access the captured groups directly after a successful pattern match.
Understanding Captured Groups with $1, $2, etc.
Each set of parentheses in a regex creates a numbered capture group. The numbering is based on the order of the opening parentheses from left to right. For example:
$1contains the substring matched by the first capturing group.$2contains the substring matched by the second capturing group.- And so on...
Importantly, these variables are set only if the match is successful, and they persist until the next successful match operation. If the match fails, their values remain unchanged from the last successful match.
Key Points and Perl-Specific Details
- Sigils: The sigil
$denotes a scalar variable;$1is a scalar holding one string. - Context: Captures are always strings; no matter the context.
- TMTOWTDI: While
$1,$2are convenient, Perl also allows you to usemy @captures = ($string =~ /(pattern)/g)to get captures in a list. - Scope and Timing: The
$1,$2variables are dynamically scoped to the last successful regex match in the current lexical scope.
Common Pitfalls & Gotchas
- Accessing
$1,$2before a successful match — they will hold values from the previous successful match or be undefined. - Using global match
/gwith capturing parentheses updates$1,$2for each match iteration. - Modifying regex or running another regex between accessing the capture variables overwrites them.
- Be careful if using
eval, threads, or other constructs that may affect the values of these variables.
Runnable Example
use strict;
use warnings;
my $text = "Name: John Doe, Age: 32";
if ($text =~ /Name:\s+(\w+)\s+(\w+),\s+Age:\s+(\d+)/) {
print "Full match succeeded.\n";
print "First name: $1\n"; # Captured first word after "Name:"
print "Last name: $2\n"; # Captured second word
print "Age: $3\n"; # Captured digits after "Age:"
} else {
print "No match!\n";
}
# Demonstrating that the capture variables persist until next match:
if ("No match here" =~ /nomatch/) {
# no capturing groups, so these won't change
}
print "After failed match, first name still: $1\n";
# Showing that new match updates captures:
if ("Alice Smith 27" =~ /(\w+)\s+(\w+)\s+(\d+)/) {
print "New match captures:\n";
print "First name: $1\n";
print "Last name: $2\n";
print "Age: $3\n";
}
This example matches a simple string with three capture groups: first name, last name, and age. After the match, you can directly access the captures using $1, $2, and $3. The second part shows that these capture variables keep their values until overwritten by another successful pattern match.
Summary
In Perl, captured groups from regexes are accessed via the special global scalar variables $1, $2, … after a successful match. They are very convenient but require care to ensure you only use them immediately after a match and before running other regex operations that could overwrite them. This behavior is part of Perl’s flexible design and its philosophy of “There’s more than one way to do it” (TMTOWTDI).
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 5ms
Full match succeeded.
First name: John
Last name: Doe
Age: 32
After failed match, first name still: John
New match captures:
First name: Alice
Last name: Smith
Age: 27
(empty)Was this helpful?
Related Questions
- How to validate email addresses using Perl regex?
- How to split a string by regex pattern in Perl?
- How to use greedy vs non-greedy quantifiers in Perl regex?
- How to match start and end of string with ^ and $ in Perl?
- How to use alternation | in Perl regex?
- How to use the qr// operator to compile regex in Perl?