$| = 1; for ( my $len = 1; ; ++ $len ) { my $rx = rx1( $len ); my @found = /$rx/ or last; print "$len: " . join( '', @found ) . "\n"; } sub rx1 { # Cheap but wasteful. # 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU) C # 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU) CP # 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU) CPM # 0 wallclock secs ( 0.01 usr + 0.00 sys = 0.01 CPU) CPME # 1 wallclock secs ( 0.61 usr + 0.00 sys = 0.61 CPU) CS201 # 4 wallclock secs ( 4.24 usr + 0.00 sys = 4.24 CPU) CS201G # 24 wallclock secs (23.48 usr + 0.01 sys = 23.49 CPU) CS201GA # 108 wallclock secs (105.62 usr + 0.02 sys = 105.64 CPU) CS201GAM # 402 wallclock secs (393.05 usr + 0.05 sys = 393.10 CPU) CS201GAME # 3917 wallclock secs (3827.03 usr + 0.50 sys = 3827.53 CPU) # # real 74m16.003s # user 72m34.080s # sys 0m0.588s my $len = shift @_; my $pat = "\\A[^\n]*?" . ( "(?:(\\S)[^\n]*?)" x $len ) . "\n" . "(?:[^\n]*?" . join( '', map "\\$_\[^\n]*?", 1 .. $len ) . "\n)+\\z"; return qr/$pat/; } sub rx2 { # Expensive but less wasteful. # 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU) C # 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU) CP # 0 wallclock secs ( 0.00 usr + 0.00 sys = 0.00 CPU) CPM # 0 wallclock secs ( 0.03 usr + 0.00 sys = 0.03 CPU) CPME # 2 wallclock secs ( 1.66 usr + 0.00 sys = 1.66 CPU) CS201 # 13 wallclock secs (13.27 usr + 0.00 sys = 13.27 CPU) CS201G # 83 wallclock secs (80.97 usr + 0.00 sys = 80.97 CPU) CS201GA # 413 wallclock secs (403.82 usr + 0.04 sys = 403.86 CPU) CS201GAM # ... to be continued (it's still working) # ... nope. It's 4x slower than the prior. I'll not bother. my $len = shift @_; my $pat = "\\A[^\n]*?" . ( "(?:(\\w)[^\n]*?)" x $len ) . "\n" . "(??{ qq<(?:" . join('', map { "[^\n>.\$$_.qq<]*>.\$$_.qq<" } 1 .. $len) . "[^\n]*\n)+>})\\z"; use re 'eval'; return qr/$pat/; }