regex before

Documentation for regex before assembled from the following types:

language documentation Regexes

From Regexes

(Regexes) regex before

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」 

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.