To include literal whitespace or # characters in a
pattern to which you've applied /x, escape them
with a backslash:
s/ # replace
\# # a pound sign
(\w+) # the variable name
\# # another pound sign
/${$1}/xg; # with the value of the global variable
Remember that comments should explain what you're doing and why, not
merely restate the code. Using "$i++
# add one
to i" is apt to lose points in
your programming course or at least get you talked about in
substellar terms by your coworkers.
The last technique for rendering patterns more legible (and thus,
more maintainable) is to place each semantic unit into a variable
given an appropriate name. We use single quotes instead of doubles so
backslashes don't get lost.
$optional_sign = '[-+]?';
$mandatory_digits = '\d+';
$decimal_point = '\.?';
$optional_digits = '\d*';
$number = $optional_sign
. $mandatory_digits
. $decimal_point
. $optional_digits;
Then use $number in further patterns:
if (/($number)/) { # parse out one
$found = $1;
}
@allnums = /$number/g; # parse all out
unless (/^$number$/) { # any extra?
print "need a number, just a number\n";
}
We can even combine all of these techniques:
# check for line of whitespace-separated numbers
m{
^ \s * # optional leading whitespace
$number # at least one number
(?: # begin optional cluster
\s + # must have some separator
$number # more the next one
) * # repeat at will
\s * $ # optional trailing whitespace
}x
which is certainly a lot better than writing:
/^\s*[-+]?\d+\.?\d*(?:\s+[-+]?\d+\.?\d*)*\s*/
Patterns that you put in variables should probably not contain
capturing parentheses or backreferences, since a capture in one
variable could change the numbering of those in others.
Clustering parentheses—that is, /(?:...)/
instead of /(...)/—though, are fine. Not
only are they fine, they're necessary if you want to apply a
quantifier to the whole variable. For example:
$number = "(?:"
. $optional_sign
. $mandatory_digits
. $decimal_point
. $optional_digits
. ")";
Now you can say /$number+/ and have the plus apply
to the whole number group. Without the grouping, the plus would have
shown up right after the last star, which would have been illegal.
One more trick with clustering parentheses is that you can embed a
modifier switch that applies only to that cluster. For example:
$hex_digit = '(?i:[0-9a-z])';
$hdr_line = '(?m:[^:]*:.*)';