MikeKulls
MikeKulls

Reputation: 1036

Defining reusable regular expression

I have defined a reusable regex to match a certain string starting with the word demux followed by digits

my $regexDemux = 'demux\d+';

and one to match words starting with ae

my $regexAe = 'ae\d+';

These work great and can be reused within my app as required. The problem comes when I want to define a regex that matches either of these

my $regexDemuxOrAe = '(demux|ae)\d+';

This works but it requires the consumer of my regex to know that it contains brackets and that it will have an influence on $1, $2 etc. For example, with the first example they can do this:

if('demux123-demux456' =~ /($regexDemux)-($regexDemux)/)
{
  print "$1  $2";
}

but to match demux or ae they need to replace $2 with $3, ie they need to know and remember that my regex contains brackets

if('ae01-demux02' =~ /($regexDemuxOrAe)-($regexDemuxOrAe)/)
{
  print "$1  $3";
}

The problem comes from the brackets in the regex having more than 1 meaning. They describe what to extract plus they also describe the boundaries for an 'or'. Is there any way to write my third regex without the brackets, or to mark those brackets as non matching?

Upvotes: 3

Views: 429

Answers (1)

pilcrow
pilcrow

Reputation: 58681

my $regexDemuxOrAe = qr/(?:demux|ae)\d+/;

The ?: will make the parentheses clustering but non-capturing (no backreferences).

Note that you probably want a first-class regex object via the qr// operator, rather than a string.

Example:

$ perl -E '$re = qr/(?:demux|ae)\d+/;
> print "$1 $2" if $ARGV[0] =~ /($re)-($re)/' ae01-demux02
ae01 demux02

Upvotes: 4

Related Questions