In Regexes§

See primary documentation in context for Lookahead assertions

To check that a pattern appears before another pattern, use a lookahead assertion via the before assertion. This has the form:

<?before pattern>

Thus, to search for the string foo which is immediately followed by the string bar, use the following regexp:

/ foo <?before bar> /

For example:

say "foobar" ~~ / foo <?before bar> /;  # OUTPUT: «foo␤»

However, if you want to search for a pattern which is not immediately followed by some pattern, then you need to use a negative lookahead assertion, this has the form:

<!before pattern>

In the following example, all occurrences of foo which is not before bar would match with

say "foobaz" ~~ / foo <!before bar> /;  # OUTPUT: «foo␤»

Lookahead assertions can be used also with other patterns, like characters ranges, interpolated variables subscripts and so on. In such cases it does suffice to use a ?, or a ! for the negate form. For instance, the following lines all produce the very same result:

say 'abcdefg' ~~ rx{ abc <?before def> };        # OUTPUT: «「abc」␤» 
say 'abcdefg' ~~ rx{ abc <?[ d..f ]> };          # OUTPUT: «「abc」␤» 
my @ending_letters = <d e f>;
say 'abcdefg' ~~ rx{ abc <?@ending_letters> };   # OUTPUT: «「abc」␤»

Metacharacters can also be used in lookahead or -behind assertions.

say "First. Second" ~~ m:g/ <?after ^^ | "." \s+> <:Lu>\S+ /
# OUTPUT: «(「First.」 「Second」)␤»

A practical use of lookahead assertions is in substitutions, where you only want to substitute regex matches that are in a certain context. For example, you might want to substitute only numbers that are followed by a unit (like kg), but not other numbers:

my @units = <kg m km mm s h>;
$_ = "Please buy 2 packs of sugar, 1 kg each";
s:g[\d+ <?before \s* @units>] = 5 * $/;
say $_;         # OUTPUT: «Please buy 2 packs of sugar, 5 kg each␤»

Since the lookahead is not part of the match object, the unit is not substituted.