Here is a function, globtore (Glob to Regular Expression), that takes the "wildcard" syntax used by the 4DOS command shell and converts it to a Perl regular expression string.

Basically, * matches anything and ? matches one character. But there are a few special cases, and 4DOS has more, such as ranges and OR's. I figure for anything that's not really basic I'll use a RegExp anyway, so I don't want to make too fancy of a globber. But the docs for 4DOS was fairly complete, so I used that as my design spec. The test data below includes the examples from the 4DOS help page.

The last_paren_match_ordinal function is another story.

Edit: chipmunk 2001-06-27

use strict; use warnings; sub last_paren_match_ordinal() { my $n= $#-; return $n; # if the above stops working, comment out the return and let the foll +owing code # run. It seems that @- is populated only up to the actual number of + captures, # while @+ always contains the max number present in the pattern. Th +is is not # documented, and may be an artifact. while ($n) { # take $n initially as a maximum, and find the highest that's actu +ally present. no strict 'refs'; last if defined $$n; --$n; } return $n; } sub globtore ($) # initial version, 27-June-2001 by JMD { my $s= shift; my $f= sub { my $n= last_paren_match_ordinal; return "($n)"; }; my @f= ( undef, # index 0 never used, uses 1..6 sub { # brackets my $s= $+; return '.' if $s eq '[?]'; # special case meaning. return '(?=\.|;|\z)' if $s eq '[]' || $s eq '[!?]'; # also sp +ecial: match "no character present". # shell uses !, change to ^. Don't worry about anything else. + Could deal with original ^ in that spot. $s =~ s/^\[!/[^/; return $s; }, sub { # ?'s before dot or end my $count= length $+; return '.?' if $count == 1; return ".{0,$count}"; }, sub { # ?'s normal case my $count= length $+; return '.' if $count == 1; return ".{$count}"; }, sub { # *'s return '.*' }, sub { # ; return '$|^'; }, sub { # other funny chars that aren't otherwise matched. my $s= $+; return "\\$s"; } ); # smash out consecutive stars $s =~ s/\*+/*/g; # do the main replacements $s =~ s/ (\[.*?\]) | # brackets in $1 (\?+(?=\.|;|\z)) | # ?'s before dot or end in $2 (\?+) | # ?'s normally in $3 (\*+) | # *'s in $4 (;) | # ; seperator in $5 ([\$\^\\\.\{\}\[\]]) # special otherwise unmatched chars in $6 /$f[last_paren_match_ordinal]->() # see above functions for massi +ve replacement block. /gex; # fix up begin/end marks $s= "^$s\$"; $s =~ s/\Q^.*\E|\Q.*\E\$//; return $s; } while (<DATA>) { chomp; s/\s+#.*$//; # allow comments in input data print "$_ ==> "; my $result= globtore ($_); print "$result\n"; } __DATA__ LETTER?.DOC # comments allowed in test data, separated by at least on +e space. funny#file#name.txt # the prev # are not comments because no space. *.DO? file{braces}.^^x *.DO[?] foobar.exe xxy *.exe l?tter?.d?? *.* st*.d* *am*.txt letter[0-9].doc ?[aeiouy]*.* [a-dt-v]ip letter[?].doc letter[].doc letter[!?].doc test[!0-9].doc # anything except digits. ??[abc]*[def]*.[pq]* letter1;v2 letter1[;]v2

In reply to Convert glob notation to regular expression by John M. Dlugosz

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.