A concise tutorial followed by a practical bug-hunting guide.
A backreference matches the exact text captured earlier. A backreference lets you reuse text that was previously matched by a capture group inside the same regex. Backreferences turn regexes from pattern recognizers into pattern comparators.
A backreference matches the exact text captured earlier in the same pattern. In this example,my $s = "hello hello"; if ( $s =~ /(\w+)\s+\1/ ) { print "Duplicate word: '$1'\n"; # matches "hello hello" }
Capturing groups are numbered left to right, ignoring non-capturing groups.
Again: capture groups are numbered left to right, based on the position of the opening parenthesis.my $s = "abab"; $s =~ /(a)(b)\1\2/; # matches "abab"
Note: renumbering happens silently if you add or remove parentheses — a major source of bugs in large regexes./(a)(b(c))/ # \1 = a # \2 = bc # \3 = c
Why/(\w+)\s+\g{1}/
Benefits:/(?<word>\w+)\s+\g{word}/
Another example:my $date = "2026-02-08"; if ($date =~ /(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/) { print "$+{d}/$+{m}/$+{y}"; # 08/02/2026 }
Named captures like first and last make it clear what each piece is, and you never have to remember whethermy $name = "Maliepaard, Reinier"; $name =~ s/^(?<last>[^,]+),\s*(?<first>.+)$/$+{first} $+{last}/; print $name; # Reinier Maliepaard
Here,/(\w+)(\s+)\g{-2}/
my $text = "this this is is Perl"; $text =~ s/\b(\w+)\s+\g{1}\b/$1/g; print $text;
Result: 'this is Perl'
You can also reuse captured text on the right‑hand side of a substitution.Heremy $name = "Maliepaard, Reinier"; $name =~ s/^([^,]+),\s*(.+)$/$2 $1/; print "$name\n"; # Reinier Maliepaard
Use:/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)/ \10 # ambiguous!
If (a) doesn’t match,/(a)?(b)\1/
Use single-quoted strings for regex literals whenever possible."(\\w+)\\s+\\1" # correct "(\w+)\s+\1"# wrong
my $s = "foo foo"; $s =~ /(?:foo)\s+(foo)/; print $1; # "foo"
my $s = "hello hello"; $s =~ /(\w+)\s+\1(\w+)/;
/\b(\w+)\s+\g{1}\b/i
/^(\w)(\w)?\g{1}$/
Backreferences are also useful to check that opening and closing tags are the same.my $s = '"Perl is fun"'; $s =~ /(["'])(.*?)\g{1}/; print $2; # Perl is fun
my $html = "hello"; # hello between <b> and </b> tags if ( $html =~ m{<([A-Za-z][A-Za-z0-9]*)>.*?\1>} ) { print "Matched a pair of <$1> tags\n"; }
my $html = "Hello world!"; # Hello between <b> and </b> tags if ($html =~ /<(\w+)>(.*?)<\/\g{1}>/) { print "Tag: $1, Content: $2";# Result: "Tag: b, Content: Hello" }