[% setvar title TITLE %]

This file is part of the Perl 6 Archive

Note: these documents may be out of date. Do not use as reference!

To see what is currently happening visit http://www.perl6.org/


Assignment within a regex


  Maintainer: Richard Proctor <richard@waveney.org>
  Date: 16 Aug 2000
  Last Modified: 1 Oct 2000
  Mailing List: perl6-language-regex@perl.org
  Number: 112
  Version: 4
  Status: Frozen


Provide a simple way of naming and picking out information from a regex without having to count the brackets.


If a regex is complex, counting the bracketed sub-expressions to find the ones you wish to pick out can be messy. It is also prone to maintainability problems if and when you wish to add to the expression. Using (?:) can be used to surpress picking up brackets, it helps, but it still gets "complex". I would sometimes rather just pickout the bits I want within the regex itself.

Suggested syntax: (?$foo= ... ) would assign the string that is matched by the patten ... to $foo when the patten matches. These assignments would be made left to right after the match has succeded but before processing a replacement or other results (or prior to a some (?{...}) or (??{...}) code). There may be whitespace between the $foo and the "=".

Potentially the $foo could be any scalar LHS, as in (?$foo{$bar}= ... ), likewise the '=' could be any asignment operator.

The camel and the docs include this example:

   if (/Time: (..):(..):(..)/) {
        $hours = $1;
        $minutes = $2;
        $seconds = $3;

This then becomes:

  /Time: (?$hours=..):(?$minutes=..):(?$seconds=..)/

This is more maintainable than counting the brackets and easier to understand for a complex regex. And one does not have to worry about the scope of $1 etc.

When does the assignment actually happen?

In general all assignments should wait to the very end, and then assign them all. However before code callouts (?{...}) and friends, the named assignments that are currently defined should be made so that the code can refer to them by name.

It may be appropriate for any assignments made before a code callout to be localised so they can unrolled should the expression finally fail.

Named Backrefs

The first versions of this RFC did not allow for backrefs. I now think this was a shortcoming. It can be done with (??{quotemeta $foo}), but I find this clumsy, a better way of using a named back ref might be (?\$foo).


The question of scoping for these assignments has been raised, but I don't currently have a feel for the "best" way to handle this. Input welcome.

Hugo: I think it should be defined to act the same as in (??{...}), whenever we get around to defining that.


Using this method for capturing wanted content, it might be desirable to stop ordinary brackets capturing, and needing to use (?:...). I therefore suggest that as an enhancement to regexes that /b (bracket?) ordinary brackets just group, without capture - in effect they all behave as (?:...).


V3 - added bit about backrefs, and brackets.

V4 - Clarified a few things and froze


Currently all $scalars in regexes are expanded before the main regex compiler gets to analyse the syntax. This problem also affects several other RFCs (166 for example). The expansion of variables in regexes needs for these (and other RFCs) to be driven from within the regex compiler so that the regex can expand as and where appropriate. Changing this should not affect any existing behaviour.


I brought this up on p5p a couple of years ago, but it was lost in the noise...

RFC 166

Perlstorm #0040