in reply to
perl look ahead regular expression that is optional?

Well, this post has been fascinating to work on. I was starting to question my ability to comprehend the English language (my mother tongue), and this morning re-read your post, including the part that said

*When the second set is present, it is always prececeded by an 'X':*

That's it, I thought -- but then I re-read the part above that says

*The second set of characters is always preceded by an X (to delimit
that this is the second set) and *__might contain a b or c__,
Only zero or one a, zero or one b, and zero or one c is allowed in the second set.

So the second set *always* starts with an 'X', and *might* contain a, b or c. How can I prove this? By writing a script to grind through all of the permutations, of course.

Here's the script that I wrote:

`#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
# Build all possible strings based on the following three rules:
# 1. Start with 'foobar'
# 2. Optionally include first set:
# a. zero or one 'a';
# b. zero or one 'b'; and
# c. zero or one 'c'.
# 3. Optionally include second set:
# a. 'X'
# b. zero or one 'a';
# c. zero or one 'b'; and
# d. zero or one 'c'.
my ( @w, %solutions );
{
@w = ('foobar');
for my $firstSet ( 0 .. 1 ) {
for my $a1 ( 0 .. 1 ) {
for my $b1 ( 0 .. 1 ) {
for my $c1 ( 0 .. 1 ) {
for my $secondSet ( 0 .. 1 ) {
for my $a2 ( 0 .. 1 ) {
for my $b2 ( 0 .. 1 ) {
for my $c2 ( 0 .. 1 ) {
if ($firstSet) {
if ($a1) { addThisChar('a'); }
if ($b1) { addThisChar('b'); }
if ($c1) { addThisChar('c'); }
}
if ($secondSet) {
addThisChar('X');
if ($a2) { addThisChar('a'); }
if ($b2) { addThisChar('b'); }
if ($c2) { addThisChar('c'); }
}
saveThatPattern();
}
}
}
}
}
}
}
}
for my $key (
sort { $solutions{$b} <=> $solutions{$a} }
sort keys %solutions
)
{
print " $key => $solutions{ $key }\n";
}
}
sub addThisChar { push( @w, shift ); }
sub saveThatPattern { $solutions{ join( '', @w ) }++; @w = ('foobar');
+ }
`

When I run this, I get the following result:

`tab@music3:/../Perlmongers$ perl -w 1056774-2.pl
foobar => 72
foobarX => 9
foobarXa => 9
foobarXab => 9
foobarXabc => 9
foobarXac => 9
foobarXb => 9
foobarXbc => 9
foobarXc => 9
foobara => 8
foobarab => 8
foobarabc => 8
foobarac => 8
foobarb => 8
foobarbc => 8
foobarc => 8
foobaraX => 1
foobaraXa => 1
foobaraXab => 1
foobaraXabc => 1
foobaraXac => 1
foobaraXb => 1
foobaraXbc => 1
foobaraXc => 1
foobarabX => 1
foobarabXa => 1
foobarabXab => 1
foobarabXabc => 1
foobarabXac => 1
foobarabXb => 1
foobarabXbc => 1
foobarabXc => 1
foobarabcX => 1
foobarabcXa => 1
foobarabcXab => 1
foobarabcXabc => 1
foobarabcXac => 1
foobarabcXb => 1
foobarabcXbc => 1
foobarabcXc => 1
foobaracX => 1
foobaracXa => 1
foobaracXab => 1
foobaracXabc => 1
foobaracXac => 1
foobaracXb => 1
foobaracXbc => 1
foobaracXc => 1
foobarbX => 1
foobarbXa => 1
foobarbXab => 1
foobarbXabc => 1
foobarbXac => 1
foobarbXb => 1
foobarbXbc => 1
foobarbXc => 1
foobarbcX => 1
foobarbcXa => 1
foobarbcXab => 1
foobarbcXabc => 1
foobarbcXac => 1
foobarbcXb => 1
foobarbcXbc => 1
foobarbcXc => 1
foobarcX => 1
foobarcXa => 1
foobarcXab => 1
foobarcXabc => 1
foobarcXac => 1
foobarcXb => 1
foobarcXbc => 1
foobarcXc => 1
tab@music3:/../Perlmongers$
`

And sure enough,

`foobarabcX` is there. So I'm now convinced that the original specification was broken.

Alex / talexb / Toronto

Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.