in reply to Re^7: Convert an array of numbers into a range
in thread Convert an array of numbers into a range

Is there a way to break the regex into two or three regexes to fix this limit?
  • Comment on Re^8: Convert an array of numbers into a range

Replies are listed 'Best First'.
Re^9: Convert an array of numbers into a range
by AnomalousMonk (Archbishop) on Sep 29, 2016 at 23:54 UTC

    c:\@Work\Perl\monks>perl -wMstrict -le "my $s = join q{,}, 1 .. 40_000; ;; $s =~ s{ \b (\d+) (?{ $1 }) \K (?: , (\d+) \b (??{ ++$^R != $2 || length($1) != length($2) }))+ }{-$2}xmsg; print qq{'$s'}; " '1-9,10-99,100-999,1000-9999,10000-40000' c:\@Work\Perl\monks>perl -wMstrict -le "my $s = join q{,}, 1 .. 150_000; ;; $s =~ s{ \b (\d+) (?{ $1 }) \K (?: , (\d+) \b (??{ ++$^R != $2 || length($1) != length($2) }))+ }{-$2}xmsg; print qq{'$s'}; " Complex regular subexpression recursion limit (32766) exceeded at -e l +ine 1. Complex regular subexpression recursion limit (32766) exceeded at -e l +ine 1. Complex regular subexpression recursion limit (32766) exceeded at -e l +ine 1. '1-9,10-99,100-999,1000-9999,10000-42767,42768-75535,75536-99999,10000 +0-132767,132768-150000' c:\@Work\Perl\monks>perl -wMstrict -le "my $s = join q{,}, 1 .. 150_000; ;; $s =~ s{ \b (\d+) (?{ $1 }) \K (?: (?: , (\d+) \b (??{ ++$^R != $2 || length($1) != length($2) })){1 +,30000} )+ }{-$2}xmsg; print qq{'$s'}; " '1-9,10-99,100-999,1000-9999,10000-99999,100000-150000'

    Updates:
    1. I should have mentioned that all these examples use the  \K regex operator, so they all require Perl version 5.10 or greater.
    2. Changed last two code examples (increased range to 150,000) to make contrast greater.
    3. (2016/10/03) If you can stomach the  \K operator (i.e., you're using Perl version 5.10+), here's a further tweak that speeds things up considerably. The critical enhancement is the use of the  "(?(condition)yes-pattern)" conditional expression (see Extended Patterns in perlre). Some other changes have been made, but they seem immaterial to the speed-up. Old (slower) version:
      c:\@Work\Perl\monks>perl -wMstrict -le "use 5.010; ;; print qq{perl version $]}; ;; my $s = join q{,}, 1 .. 1_500_000; ;; my $end_point = qr{ , (\d++) \b (??{ ++$^R != $2 || length($1) != length($2) }) }xms; ;; my $start = time; use re 'eval'; $s =~ s{ \b (\d++) (?{ $1 }) \K (?: $end_point{1,32766})+ }{-$2}xmsg; print qq{'$s'}; printf qq{in %d seconds \n}, time - $start; " perl version 5.010001 '1-9,10-99,100-999,1000-9999,10000-99999,100000-999999,1000000-1500000 +' in 18 seconds
      New (faster) version:
      c:\@Work\Perl\monks>perl -wMstrict -le "use 5.010; ;; print qq{perl version $]}; ;; my $s = join q{,}, 1 .. 1_500_000; ;; my $end_point = qr{ , (\d++) (?(?{ ++$^R != $2 || length($1) != length($2) }) (*F)) }xms; ;; my $start = time; use re 'eval'; $s =~ s{ \b (\d++) (?{ $1 }) \K (?: $end_point{1,32766})+ }{-$2}xmsg; print qq{'$s'}; printf qq{in %d seconds \n}, time - $start; " perl version 5.010001 '1-9,10-99,100-999,1000-9999,10000-99999,100000-999999,1000000-1500000 +' in 3 seconds

    Give a man a fish:  <%-{-{-{-<

      I will try these and report back. Thanks a lot.