Roman Hausner wrote:
> I am disappointed to learn that Ruby obviously implements yet another
> regular expression library that does not avoid very slow matching
> failures.
>
> Just try this program:
>
> str1 = "foo " * 70 + "foo ";
> str2 = "foo " * 70 + "fo ";
>
> strings = str1, str2;
>
> strings.each { |s|
>   print "Matching #{s}\n";
>   if(s =~ /^(\s*foo\s*)*$/)
>     print "YES!\n";
>   else
>     print "NO!\n";
>   end
> }
>
> and compare it with this perl program:
> my $str1 = ("foo " x 70) . "foo ";
> my $str2 = ("foo " x 70) . "fo ";
>
> my @strings = ( $str1, $str2 );
>
> foreach $s ( @strings ) {
> print "Matching $s\n";
> if($s =~ /^(\s*foo\s*)*$/) {
>   print "YES!\n";
> } else {
>   print "NO!\n";
> }
> }
>
> On my machine, the perl version takes 0.229 seconds. The ruby version
> was still running after 519.662 seconds when I killed it.
>
> Is this being taken care of for the next release?
>
> --
> Posted via http://www.ruby-forum.com/.

Here's the way to do it.

strings = " foo " * 70 + "foo ",
          "foo " * 70 + "foo ",
          " foo " * 70 + "fo ",
          ""

strings.each { |s|
  puts "Matching #{s}"
  if s =~ /^  \s*  # May start with whitespace.
              # The rest of the string must be 0 or more
              # occurrences of "foo" plus whitespace.
              (?:  foo \s+  ) *
         $/x
    puts "YES!"
  else
    puts "NO!"
  end
}