Regular Expression Basics
18.1 Matching
use v5.36;
my $text = 'The year 2025 was great; 2026 will be better.';
if ($text =~ /year (\d{4})/) { # match operator m// (the m is optional with //)
say "Found year: $1"; # $1, $2 ... capture groups
}
say 'No digits' if $text !~ /\d/;
my @years = $text =~ /(\d{4})/g; # list context + /g: all matches
my ($first) = $text =~ /(\d+)/; # first capture
while ($text =~ /(\d{4})/g) { # scalar context + /g: iterate
say "Year $1 at position ", pos($text);
}
for (@lines) { say if /error/i } # matches against $_ by default
my $re = qr/\b(\w+)@(\w+\.\w+)\b/; # precompiled regex object
if ('[email protected]' =~ $re) { say "user=$1 domain=$2" }18.2 Regex Syntax Summary
Any character except newline (any character with /s) Digit, word character, whitespace [abc] / [^abc] / [a-z]
Start/end of string (of a line with /m) \A / \z / \Z
Absolute start / end / end before a final newline Word boundary / non-boundary 0+, 1+, 0 or 1 (greedy) {n} {n,} {n,m} Exact / at least / range *? +? ?? {n,m}? Non-greedy (lazy) Possessive (no backtracking) \1, \g1, \g{-1} \p{L} / \p{Lu} / \p{Greek}
18.3 Modifiers
Global (all matches) Multiline: ^ and $ match at line boundaries Single-line: . matches newline
Extended: whitespace and comments allowed in the pattern Compile once (obsolete; use qr//)
Evaluate the replacement as code (in s///) Return the modified string, leaving the original unchanged (in s///, tr///) Make plain () non-capturing (5.22+) /a / /aa / /u / /l
ASCII-restrict \d\w\s / Unicode rules / locale rules Preserve ${^MATCH} and friends (default behavior in modern Perl)
18.4 Substitution and Transliteration
my $s = 'Hello World';
$s =~ s/World/Perl/; # replace the first match
$s =~ s/o/0/g; # replace all
(my $copy = $s) =~ s/l/L/g; # copy, then modify the copy
my $new = $s =~ s/\s+/_/gr; # /r returns a new string (5.14+)
$s =~ s/(\w+)/\u$1/g; # capitalize each word
$s =~ s/(\d+)/$1 * 2/ge; # /e: replacement is Perl code
$s =~ s{^\s+|\s+$}{}g; # alternative delimiters
my $count = ($text =~ s/foo/bar/g); # returns the number of substitutions
(my $t = $s) =~ tr/a-z/A-Z/; # transliterate characters
my $vowels = ($s =~ tr/aeiouAEIOU//); # count characters
$s =~ tr/a-zA-Z//cd; # delete everything except letters (/c complement, /d delete)
$s =~ tr/ //s; # squeeze repeated spaces18.5 Captures and Match Variables
if ('2025-10-24' =~ /^(\d{4})-(\d{2})-(\d{2})$/) {
my ($y, $m, $d) = ($1, $2, $3);
}
if ('2025-10-24' =~ /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/) {
say "Year: $+{year}, Month: $+{month}"; # named captures in %+
}
my ($y, $m, $d) = '2025-10-24' =~ /(\d+)-(\d+)-(\d+)/; # list assignment (preferred)
# $& (match), $` (prematch), $' (postmatch): safe to use in modern Perl (no global slowdown since 5.20)
# @- and @+: offsets of the match and groups