ZetCode

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.

ims.pl
#!/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.

x.pl
#!/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.

n.pl
#!/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.

ascii.pl
#!/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.

inline.pl
#!/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

In this article we have covered the /i, /m, /s, /x, /xx, /n and /a modifiers, and the inline forms.

Source

perlre: Modifiers

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Perl tutorials.