Primes and the Perl regular expression parser

Okay, I've read about this a couple of times, but someone asked on a work mailing list today and I finally sat down and deciphered it. If you're not a Perl fan, skip ahead. This:

perl -wle '$_ = 1; (1 x $_) !~ /^(11+)\1+$/ && print while $_++'

Prints primes. But it's cool to understand why it prints primes.

There are two expressions there. $_ = 1; simply assigns 1 to $_.

Breaking the second expression apart, (1 x $_) creates a string of '1's, $_ characters long. !~ says "apply the following regular expression to the preceding string". If this expression (the application of the regular expression to the string) is true, the && print prints $_, and the while $_++ increments $_ and tries the expression again.

So, the regular expression: ^(11+)\1+$

^ says match the beginning of the expression.

(11+) says match 1, followed by one or more 1s (or two or more 1s) and the parentheses group this into the expression that can be referenced with \1.

\1+ says one or more occurrences of the first group (as explained above, and the $ says "end the string".

So, in C, if "b" is the length of the string, the regular expression basically says:

for (a = 2; a < b; a++)
{
if (0 == a % b)
return 1;
}

That !~ negates that, so the print only gets executed if the expression is false.


Friday, October 16th, 1998 danlyke@flutterby.com