Perl regex modifiers
last modified October 20, 2026
Regex modifiers change the meaning of a pattern without changing its text. They
come after the closing delimiter, such as /gi, or inside the
pattern as (?i). This article covers the ones that affect matching
rules; /g, /e and /r are discussed in the
articles on matching and substitution.
The /i, /m and /s modifiers
Modifiers are flags written after the closing delimiter that change how a
pattern is interpreted. The most common ones are /i for
case-insensitive matching, /m to make ^ and
$ match at line boundaries, and /s to let the dot
match a newline.
#!/usr/bin/perl use strict; use warnings; use v5.34.0; my $text = "First line\nsecond LINE\nthird line"; say "plain: ", scalar(() = $text =~ /line/g); say "/i: ", scalar(() = $text =~ /line/gi); my @starts = $text =~ /^(\w+)/g; say "no /m: @starts"; @starts = $text =~ /^(\w+)/gm; say "/m: @starts"; say "dot vs newline: ", ($text =~ /First.*third/ ? 'match' : 'no match'); say "with /s: ", ($text =~ /First.*third/s ? 'match' : 'no match'); say "with /is: ", ($text =~ /FIRST.*THIRD/is ? 'match' : 'no match');
The text has three lines. Case-insensitive matching finds the extra
LINE. Without /m, ^ matches only at the
start of the string, but with it each line start is found. The dot normally
stops at a newline, so First.*third fails until /s is
added. Modifiers can be combined, as in /is.
$ perl ims.pl plain: 2 /i: 3 no /m: First /m: First second third dot vs newline: no match with /s: match with /is: match
The /x and /xx modifiers
With /x, whitespace in the pattern is ignored and #
starts a comment, so complicated patterns can be laid out and explained. The
/xx form, added in Perl 5.26, also ignores spaces and tabs inside
bracketed character classes.
#!/usr/bin/perl
use strict;
use warnings;
use v5.34.0;
my $phone = qr/
^
\(? (\d{3}) \)? # area code, optional parentheses
[\s.-]? # separator
(\d{3}) # exchange
[\s.-]?
(\d{4}) # number
$
/x;
for my $p ('(555) 123-4567', '555.123.4567', '5551234567', '55-1234') {
if (my @parts = $p =~ $phone) {
say "$p => @parts";
} else {
say "$p => no match";
}
}
say "literal space needs escaping: ", ('a b' =~ /a\ b/x ? 'yes' : 'no');
say "space inside a class, /x: ", ('a b' =~ /^[a b]+$/x ? 'yes' : 'no');
say "space inside a class, /xx: ", ('a b' =~ /^[a b]+$/xx ? 'yes' : 'no');
The phone pattern is split into labeled lines, and the captured parts are
returned in list context. A literal space in an /x pattern must be
escaped or placed in a class. With /x a space inside a class is
still significant, but with /xx it is dropped, so the same text
fails to match.
$ perl x.pl (555) 123-4567 => 555 123 4567 555.123.4567 => 555 123 4567 5551234567 => 555 123 4567 55-1234 => no match literal space needs escaping: yes space inside a class, /x: yes space inside a class, /xx: no
The /n modifier
Starting with Perl 5.22, /n turns all unnamed groups into
non-capturing ones. Named groups still capture. It is a cheap way to avoid
unwanted captures and the overhead that comes with them.
#!/usr/bin/perl
use strict;
use warnings;
use v5.34.0;
my $s = 'John Smith';
if (my @groups = $s =~ /(\w+) (\w+)/) {
say "with captures: @groups";
}
my @none = $s =~ /(\w+) (\w+)/n;
say "with /n: ", scalar(@none), " element(s): @none";
if ($s =~ /(?<first>\w+) (\w+)/n) {
say "named still captured: $+{first}";
}
say "non-capturing groups: ", join ',', 'ab12' =~ /^(?:[a-z]+)(\d+)$/;
Normally the match in list context returns the two captured words. With
/n nothing is captured, so the match just returns the true value 1.
The named group is the exception and is still available in %+. The
last line uses an explicit (?:...) group, which does the same for a
single group without a flag.
$ perl n.pl with captures: John Smith with /n: 1 element(s): 1 named still captured: John non-capturing groups: 12
The /a and /u modifiers
By default, \d, \w and POSIX classes match characters
from all of Unicode. The /a modifier restricts them to ASCII, which
is useful for validating identifiers and numbers. The /u modifier
forces Unicode rules, and /l uses the current locale.
#!/usr/bin/perl
use strict;
use warnings;
use v5.34.0;
my $arabic = "\x{663}";
my $greek = "\x{3b1}";
say "digit \\d matches U+0663: ", ($arabic =~ /^\d$/ ? 'yes' : 'no');
say "digit \\d with /a: ", ($arabic =~ /^\d$/a ? 'yes' : 'no');
say "word \\w matches Greek alpha: ", ($greek =~ /^\w$/ ? 'yes' : 'no');
say "word \\w with /a: ", ($greek =~ /^\w$/a ? 'yes' : 'no');
say "[[:alpha:]] with /a: ", ($greek =~ /^[[:alpha:]]$/a ? 'yes' : 'no');
my $both = "A\x{3b1}";
say "ASCII-only word chars: ", join '', $both =~ /\w/ag;
The Arabic-Indic digit three, U+0663, counts as a digit for a plain
\d, and the Greek alpha counts as a word character, but neither
does with /a. The code points are written with \x{...}
escapes. Under /a the global match of \w returns only
the ASCII letter.
$ perl ascii.pl digit \d matches U+0663: yes digit \d with /a: no word \w matches Greek alpha: yes word \w with /a: no [[:alpha:]] with /a: no ASCII-only word chars: A
Inline modifiers
Modifiers can be switched on inside the pattern with (?i) and off
with (?-i). The form (?i:...) limits the change to a
group, and (?^:...) restores the defaults.
#!/usr/bin/perl
use strict;
use warnings;
use v5.34.0;
say "inline (?i): ", ('HELLO world' =~ /(?i)hello world/ ? 'yes' : 'no');
say "scoped (?i:): ", ('HELLO world' =~ /(?i:hello) world/ ? 'yes' : 'no');
say "scoped (?i:): ", ('HELLO WORLD' =~ /(?i:hello) world/ ? 'yes' : 'no');
my $case_free = qr/perl/i;
say "outer /x kept? ", ('PERL 5' =~ /^$case_free\s5$/ ? 'yes' : 'no');
say "turn off with (?-i): ", ('PERL perl' =~ /(?i)perl (?-i)perl/ ? 'yes' : 'no');
say "turn off with (?-i): ", ('PERL PERL' =~ /(?i)perl (?-i)perl/ ? 'yes' : 'no');
say "defaults with (?^:): ", ('ABC' =~ /(?i)(?^:abc)/ ? 'yes' : 'no');
An inline (?i) applies to the rest of the enclosing group. In the
scoped form only the word hello is case-insensitive, so HELLO
world matches and HELLO WORLD does not. With
(?-i) the flag is turned off again, and the caret form resets the
group to the defaults. Inline flags are the way to apply different rules to
different parts of the same pattern.
$ perl inline.pl inline (?i): yes scoped (?i:): yes scoped (?i:): no outer /x kept? yes turn off with (?-i): yes turn off with (?-i): no defaults with (?^:): no
Best Practices
- Use /x for anything non-trivial: comments and spacing are free.
- Prefer /a for ASCII validation: otherwise
\daccepts digits from other scripts. - Scope inline flags:
(?i:...)is safer than a bare(?i). - Add /n when captures are not needed: it avoids accidental capture groups.
- Remember /m and /s are independent: one controls anchors, the other the dot.
In this article we have covered the /i, /m,
/s, /x, /xx, /n and
/a modifiers, and the inline forms.
Source
Author
List all Perl tutorials.