in reply to Bug in glob2pat?

I realised that there are even more problems with the original glob2pat in the Cookbook. The POSIX standard says that the only character inside [] that changes between glob and regular expressions is ! to ^. The Cookbook code does not do that conversion, but does others that are wrong and escapes other special characters, like the ':' in a POSIX characers class.

I gave up trying to use an RE to do this and ended-up with a brute force approach. Elegant it is not, but it does work:
sub glob2pat { my $globstr = shift; my $inside_br = 0; my @chars = (split '', $globstr); # C style used because I need to skip-ahead and look-behind for (my $i; $i < @chars; $i++) { if ($chars[$i] eq '\\') { $i++; # ignore next char } elsif ($chars[$i] eq '[') { $inside_br++; # Allow for nested [] } elsif ($chars[$i] eq ']' && $inside_br) { $inside_br--; } elsif ($chars[$i] eq '!' && $inside_br && $chars[$i-1] eq '[') + { # ! only means 'not' at the front of the [] list $chars[$i] = '^' } elsif (! $inside_br) { if ($chars[$i] eq '*') { $chars[$i] = '.*' } elsif ($chars[$i] eq '?') { $chars[$i] = '.' } } } local $" = ''; return "^@chars\$"; }
Of course improvements are welcome, here is one of my test patterns: '?\?*  [!-0-9?[:upper:]!*?]*'
which gives: '^.\?.*  [^-0-9?[:upper:]!*?].*$'