For a list of things to match in any order, what I did was:
my $regexLockParams = '(?:[\\s,]+'
."|(?:$regexSubstringOf{angle}|$regexSubstringOf{offset})\\s*$rege
+xNumber"
."|$regexSubstringOf{dispersion}\\s*$regexNumber"
#."|..."
.')+';
The way that works is that it matches (?:A|B|C)+, any of the three submatches can match, and then goes back to try for more.
In this case, A is whitespace, and not captured. B matches either "angle" or "offset", followed by a real number which it captures into $1. C matches "dispersion" followed by a real number which it captures into $2.
At the end of the match, you are left with $1 containing the angle, or undef if it was unspecified, and $2 containing the dispersion or again undef. Order doesn't matter since the alternation is repeated.
IE:
angle 5, dispersion20 ==> $1=5 $2=20
disp1ang4 ==> $1=4 $2=1
d42 ==> $1=undef $2=42
CAVEAT:
Each alternation branch must fail to match before the capture is closed, otherwise that capture variable will be overwritten and not get restored to the previous value when the engine backtracks past the capture.
You can use a lookahead (?=...)to ensure that the remainder of the branch will match if necessary. (In the above example, the capture was last, so there was no postfix to worry about)
sub safeCapture
{
# Workaround for Regex issue in which backtracked captures inside
+alternations inside repetition, will stomp on the capture value.
my $prefix = shift;
my $cap = shift;
my $postfix = shift;
return "$prefix($cap(?=$postfix))$postfix";
}
|