Skip to main content

Windows Wildcards and Windows Regular Expressions

Windows wildcards let you specify a file or group of files by typing a partial filename. The appropriate directory is scanned to find all of the files that match the partial name. You can also use regular expressions to specify files when using TCC (see below).

Wildcards are usually used to specify which files should be processed by a command. If you need to specify which files should not be processed, see File Exclusion Ranges (for TCC internal commands), or EXCEPT (for external commands).

Most internal commands in TCC or CMD accept filenames with wildcards anywhere that a full filename can be used. There are two wildcard characters, the asterisk * and the question mark ?. Additionally, in TCC you can specify a set of characters (see below).

WARNING: When you use a wildcard search for files to process in a command like FOR or DO, and you create new filenames (whether by renaming existing files or by creating new files), the new filenames may match your selection wildcard, and cause you to process them again.

Asterisk * wildcard

An asterisk * in a file specification means "a set of any characters or no character in this position". For example, the following command will display a list of all files (including directories, but excluding those files and directories with at least one of the attributes hidden and system) in the current directory:

    dir *

If you want to see all of the files with a .TXT extension:

    dir *.txt

If you know that the file you are looking for has a base name that begins with ST and an extension that begins with .D, you can find it this way. Filenames such as STATE.DAT, STEVEN.DOC, and ST.D will all be displayed:

    dir st*.d*

TCC also lets you also use the asterisk to match filenames with specific letters somewhere inside the name. The following example will display any file with a .TXT extension that has the letters AM together anywhere inside its base name. It will, for example, display AMPLE.TXT, STAMP.TXT, CLAM.TXT, and AM.TXT, but it will ignore CLAIM.TXT:

    dir *am*.txt

Question mark ? wildcard

A question mark ? matches any single filename character. You can put the question mark anywhere in a filename and use as many question marks as you need. The following example will display files with names like LETTER.DOC, LATTER.DAT, and LITTER.DU:

    dir l?tter.d??

The use of an asterisk wildcard before other characters, and of the character ranges discussed below, are enhancements to the standard Microsoft wildcard syntax, and are not likely to work properly with software other than TCC.

"Extra" question marks in your wildcard specification are ignored if the file name is shorter than the wildcard specification. For example, if you have files called LETTER.DOC, LETTER1.DOC, and LETTERA.DOC, this command will display all three names:

  dir letter?.doc

The file LETTER.DOC is included in the display because the "extra" question mark at the end of LETTER? is ignored when matching the shorter name LETTER.

Character set wildcards

In some cases, the ? wildcard may be too general. TCC (but not CMD) also allows you to specify the exact set of what characters you want to accept (or exclude) in a particular position in the filename by using square brackets [ ]. Inside the brackets, you can put the individual acceptable characters or ranges of characters. For example, if you wanted to match LETTER0.DOC through LETTER9.DOC, you could use this command:

  dir letter[0-9].doc

You could find all files that have a vowel as the second letter in their name this way. This example also demonstrates how to mix the wildcard characters:

  dir ?[aeiouy]*

You can exclude a group of characters or a range of characters by using an exclamation mark [!] as the first character inside the brackets. This example displays all filenames that are at least 2 characters long except those which have a vowel as the second letter in their names:

  dir ?[!aeiouy]*

The next example, which selects files such as AIP, BIP, and TIP but not NIP, demonstrates how you can use multiple ranges inside the brackets. It will accept a file that begins with an A, B, C, D, T, U, or V:

  dir [a-dt-v]ip

You may use a question mark character inside the brackets, but its meaning is slightly different than a normal (unbracketed) question mark wildcard. A normal question mark wildcard matches any character, but will be ignored when matching a name shorter than the wildcard specification, as described above. A question mark inside brackets will match any character, but will not be discarded when matching shorter filenames. For example:

  dir letter[?].doc

will display LETTER1.DOC and LETTERA.DOC, but not LETTER.DOC.

You can repeat any of the wildcard characters in any combination you desire within a single file name. For example, the following command lists all files which have an A, B, or C as the third character, followed by zero or more additional characters, followed by a D, E, or F, followed optionally by some additional characters, and with an extension beginning with P or Q. You probably won't need to do anything this complex, but we've included it to show you the flexibility of extended wildcards:

  dir ??[abc]*[def]*.[pq]*

You can also use the square bracket wildcard syntax to work around a conflict between long filenames containing semicolons [;], and the use of a semicolon to indicate an include list. For example, if you have a file on an LFN drive named C:\DATA\LETTER1;V2 and you enter this command:

  del \data\letter1;v2

you will not get the results you expect. Instead of deleting the named file, TCC will attempt to delete LETTER1 and then V2, because the semicolon indicates an include list. However if you use square brackets around the semicolon it will be interpreted as a filename character, and not as an include list separator. For example, this command would delete the file named above:

  del \data\letter1[;]v2

Matching short file names (SFNs)

If the Search for SFNs configuration option is set, in TCC wildcard searches accept a match on either  the LFN or the SFN to match the behavior of CMD. This may cause some files to be found because of SFN match only. In most situations this is not actually desirable, and can be avoided by disabling the option (the default).

Note: The wildcard expansion process will attempt to allow both CMD-style "extension" matching (only one extension, at the end of the word) and the advanced TCC filename matching (allowing things like *.*.abc) when an asterisk is encountered in the destination of a  COPY, MOVE or REN / RENAME command.

Wildcards in directory names

TCC (but not CMD) supports wildcards in the directory names (but not in the drive name), for internal TCC commands and functions. These types of wildcards are common in Linux, but are not supported in CMD or most Windows apps.

You can control the subdirectory recursion by specifying * or ** in the path. A * will match a single subdirectory level; a ** will match any all subdirectory levels for that pathname. Directory wildcards also support regular expressions. Directory wildcards cannot be used with the /O:... option (which sorts entries before executing the command). And think very carefully before using directory wildcards with a /S (recurse subdirectories) option, as this will almost certainly return unexpected results!

For example, to delet the file foobar in any subdirectory of c:\test\test2 (but not in any of their subdirectories):

    del c:\test\test2\*\foobar

To delete the file foobar in any subdirectory under c:\test (and all of their subdirectories) that has "foo" anywhere in the name:

    del c:\test\**\*foo*\foobar

To delete the file foobar in any subdirectory of c:\test that begins with a t and ends with a 2:

    del c:\test\t*2\foobar

There are a few commands which do not support directory wildcards, as they would be meaningless or destructive (for example, TREE, @FILEOPEN, @FILEDATE, etc.).

Windows Regular Expressions in TCC

In addition to extended Windows wildcards (*, ?, and [...]), TCC supports the use of regular expression wildcards for file name matching and replacement in internal file handling commands (COPY, DEL, DIR, MOVE, REN, etc.). You can choose the regular expression syntax you want to use - TCC supports Perl, Ruby, Java, grep, POSIX, gnu, Python, and Emacs regular expressions.

The syntax is:

    ::regex

For example:

    dir ::ca[td]

Note that using Windows regular expressions will slow your directory searches slightly --  since Windows doesn't support them natively, the TCC parser has to convert the filename to *, retrieve all filenames, and then match them to the regular expression.

If you have any special characters (whitespace, redirection characters, escape characters, etc.) in your regular expression, you will need to enclose them in double quotes. For example:

    dir "::^\w{1,8}\.btm$"

For more information on regular expression wildcard syntax, see Regular Expression Syntax in the Take Command help.

To simplify your regular expression creation and testing, Take Command and TCC include a regular expression analyzer dialog (Ctrl-F7 from the TCC command line, or under the Tools menu in Take Command.) There are two edit boxes:

  1. The first is for the regular expression to test.. If the regular expression is valid, the dialog will display a green check to the right of the expression edit box. If the regular expression is invalid, the dialog will display a red X.
  2. The second edit box is for the text you want to match against the regular expression. If the text matches the regular expression, the dialog will display a green check to the right of the test edit box. If the text doesn't match, the dialog will display a red X.

TCC Windows Regular Expressions / Windows Wildcards Analyzer

Onigmo Regular Expressions Syntax (Version 6.2.0) in Take Command / TCC

This section covers the default Ruby regular expression syntax. For information on other regular expression syntax (Perl, Python, Java, etc.), see the appropriate documentation for that product.

Syntax elements

\ escape (enable or disable meta character meaning)
| alternation
(...) group
[...] character class  

Characters

\t horizontal tab (0x09)
\v vertical tab   (0x0B)
\n newline        (0x0A)
\r return         (0x0D)
\b back space     (0x08)
\f form feed      (0x0C)
\a bell           (0x07)
\e escape         (0x1B)
\nnn octal char            (encoded byte value)
\xHH hexadecimal char      (encoded byte value)
\x{7HHHHHHH} wide hexadecimal char (character code point value)
\cx control char          (character code point value)
\C-x control char          (character code point value)
\M-x meta  (x|0x80)        (character code point value)
\M-\C-x meta control char     (character code point value)
(* \b is effective in character class [...] only)

Character types

. any character (except newline)
\w word character
Not Unicode:
            alphanumeric, "_" and multibyte char. 
Unicode:
General_Category -- (Letter|Mark|Number|Connector_Punctuation)
\W       non word char
\s whitespace char
Not Unicode:
\t, \n, \v, \f, \r, \x20
Unicode:
0009, 000A, 000B, 000C, 000D, 0085(NEL), 
General_Category -- Line_Separator
                     -- Paragraph_Separator
                      -- Space_Separator
\S non whitespace char
\d decimal digit char
Unicode: General_Category -- Decimal_Number
\D non decimal digit char
\h hexadecimal digit char   [0-9a-fA-F]
\H non hexadecimal digit char
Character Property
* \p{property-name}
* \p{^property-name}    (negative)
* \P{property-name}     (negative)
property-name:
+ works on all encodings
Alnum, Alpha, Blank, Cntrl, Digit, Graph, Lower, Print, Punct, Space, Upper, XDigit, Word, ASCII,
     + works on UTF8, UTF16, UTF32
  \R       Linebreak
           Unicode:
             (?>\x0D\x0A|[\x0A-\x0D\x{85}\x{2028}\x{2029}])
           Not Unicode:
             (?>\x0D\x0A|[\x0A-\x0D])
  \X       eXtended grapheme cluster
           Unicode:
             (?>\P{M}\p{M}*)
           Not Unicode:
             (?m:.)

Quantifier

greedy
?       1 or 0 times
*       0 or more times
+       1 or more times
{n,m}   at least n but not more than m times
{n,}    at least n times
{,n}    at least 0 but not more than n times ({0,n})
{n}     n times
reluctant
??      1 or 0 times
*?      0 or more times
+?      1 or more times
{n,m}?  at least n but not more than m times  
{n,}?   at least n times
{,n}?   at least 0 but not more than n times (== {0,n}?)
possessive (greedy and does not backtrack after repeated)
?+      1 or 0 times
*+      0 or more times
++      1 or more times
({n,m}+, {n,}+, {n}+ are possessive op. in ONIG_SYNTAX_JAVA only)
ex. /a*+/ === /(?>a*)/

Anchors

^ beginning of the line
$ end of the line
\b word boundary
\B not word boundary
\A beginning of string
\Z end of string, or before newline at the end
\z end of string
\G matching start position (*)

Character class

^... negative class (lowest precedence operator)
x-y range from x to y
[...] set (character class in character class)
..&&.. intersection (low precedence at the next of ^)
          
ex. [a-w&&[^c-g]z] ==> ([a-w] AND ([^c-g] OR z)) ==> [abh-w]
* If you want to use '[', '-', ']' as a normal character in a character class, you should escape these characters by '\'.
POSIX bracket ([:xxxxx:], negate [:^xxxxx:])
Not Unicode Case:
alnum alphabet or digit char
alpha alphabet
ascii code value: [0 - 127]
blank \t, \x20
cntrl
digit 0-9
graph include all of multibyte encoded characters
lower
print include all of multibyte encoded characters
punct
space \t, \n, \v, \f, \r, \x20
upper
word alphanumeric, "_" and multibyte characters
xdigit 0-9, a-f, A-F
Unicode Case:
alnum Letter | Mark | Decimal_Number
alpha Letter | Mark
ascii 0000 - 007F
blank Space_Separator | 0009
cntrl Control | Format | Unassigned | Private_Use | Surrogate
digit Decimal_Number
graph [[:^space:]] && ^Control && ^Unassigned && ^Surrogate
lower Lowercase_Letter
print [[:graph:]] | [[:space:]]
punct Connector_Punctuation | Dash_Punctuation | Close_Punctuation | Final_Punctuation | Initial_Punctuation | Other_Punctuation | Open_Punctuation
space Space_Separator | Line_Separator | Paragraph_Separator | 0009 | 000A | 000B | 000C | 000D | 0085
upper Uppercase_Letter
word Letter | Mark | Decimal_Number | Connector_Punctuation
xdigit 0030 - 0039 | 0041 - 0046 | 0061 - 0066  (0-9, a-f, A-F)

Extended groups

(?#...) comment
(?imxdau-imx)      option on/off
i: ignore case
m: multi-line (dot(.) match newline)
x: extended form
character set option (character range option)
d: Default (compatible with Ruby 1.9.3)
\w, \d and \s doesn't match non-ASCII characters.
\b, \B and POSIX brackets use the each encoding's rules.
a: ASCII
ONIG_OPTION_ASCII_RANGE option is turned on.
 \w, \d, \s and POSIX brackets doesn't match non-ASCII characters.
\b and \B use the ASCII rules.
 u: Unicode
ONIG_OPTION_ASCII_RANGE option is turned off.
 \w (\W), \d (\D), \s (\S), \b (\B) and POSIX brackets use the each encoding's rules.
(?imxdau-imx:subexp) option on/off for subexp
(?:subexp) not captured group
(subexp) captured group
(?=subexp) look-ahead
(?!subexp) negative look-ahead
(?<=subexp) look-behind
(?<!subexp) negative look-behind
Subexp of look-behind must be fixed character length. But different character length is allowed in top level alternatives only.
ex. (?<=a|bc) is OK. (?<=aaa(?:b|cd)) is not allowed.
In negative-look-behind, captured group isn't allowed, but shy group(?:) is allowed.
\K keep
Another expression of look-behind. Keep the stuff left of the \K, don't include it in the result.
(?>subexp) atomic group
don't backtrack in subexp.
(?<name>subexp) define named group
(All characters of the name must be a word character. And first character must not be a digit or upper case)
Not only a name but a number is assigned like a captured group.
Assigning the same name as two or more subexps is allowed. In this case, a subexp call can not be performed although the back reference is possible.
  (?(cond)yes-subexp), (?(cond)yes-subexp|no-subexp)
                    conditional expression
                    Matches yes-subexp if (cond) yields a true value, matches no-subexp otherwise.
                    Following (cond) can be used:
                    (n)  (n >= 1)
                        Checks if the numbered capturing group has matched something.
                    (<name>), ('name')
                        Checks if a group with the given name has matched something.

Back reference

\n back reference by group number (n >= 1)
\k<n> back reference by group number (n >= 1)
\k'n' back reference by group number (n >= 1)
\k<-n> back reference by relative group number (n >= 1)
\k'-n' back reference by relative group number (n >= 1)
\k<name> back reference by group name
\k'name' back reference by group name
In the back reference by the multiplex definition name, a subexp with a large number is referred to preferentially. (When not matched, a group of the small number is referred to.)
* Back reference by group number is forbidden if named group is defined in the pattern and ONIG_OPTION_CAPTURE_GROUP is not setted.

Back reference with nest level
level: 0, 1, 2, ...
\k<n+level>     (n >= 1)
\k<n-level>     (n >= 1)
\k'n+level'     (n >= 1)
\k'n-level'     (n >= 1)
\k<-n+level>    (n >= 1)
\k<-n-level>    (n >= 1)
\k'-n+level'    (n >= 1)
\k'-n-level'    (n >= 1)
\k<name+level>
\k<name-level>
\k'name+level'
\k'name-level'
Destinate relative nest level from back reference position.  
example 1.
/\A(?|.|(?:(?.)\g\k<b+0>))\z/.match("reer")
example 2.
r = Regexp.compile(<<'__REGEXP__'.strip, Regexp::EXTENDED)
(?<element> \g<stag> \g<content>* \g<etag> ){0}
(?<stag> < \g<name> \s* > ){0}
(?<name> [a-zA-Z_:]+ ){0}
(?<content> [^<&]+ (\g<element> | [^<&]+)* ){0}
(?<etag> </ \k<name+1> >){0}
\g<element>
__REGEXP__
p r.match('<foo>f<bar>bbb</bar>f</foo>').captures

Subexp call ("Tanaka Akira special")

\g<name> call by group name
\g'name' call by group name
\g<n> call by group number (n >= 1)
\g'n' call by group number (n >= 1)
\g<0>       call the whole pattern recursively
\g'0'       call the whole pattern recursively
\g<-n>      call by relative group number (n >= 1)
\g'-n'      call by relative group number (n >= 1)
\g<+n>      call by relative group number (n >= 1)
\g'+n'      call by relative group number (n >= 1)
* left-most recursive call is not allowed.
ex. (?<name>a|\g<name>b)   => error
(?<name>a|b\g<name>c)  => OK
* Call by group number is forbidden if named group is defined in the pattern and ONIG_OPTION_CAPTURE_GROUP is not set.
* If the option status of called group is different from calling position then the group's option is effective.
ex. (?-i:\g<name>)(?i:(?<name>a)){0}  match to "A"
Perl syntax:: use (?&name), (?n), (?-n), (?+n), (?R) or (?0) instead.

Captured group

Behavior of the no-named group (...) changes with the following conditions. (But named group is not changed.)
case 1. /.../    (named group is not used, no option)
(...) is treated as a captured group.
case 2. /.../g    (named group is not used, 'g' option)
(...) is treated as a no-captured group (?:...).
case 3. /..(?<name>..)../    (named group is used, no option)
(...) is treated as a no-captured group (?:...).
numbered-backref/call is not allowed.
case 4. /..(?<name>..)../G    (named group is used, 'G' option)
(...) is treated as a captured group.
numbered-backref/call is allowed.
where
g:  ONIG_OPTION_DONT_CAPTURE_GROUP
G:  ONIG_OPTION_CAPTURE_GROUP

Syntax dependent options

+ RUBY
(?m): dot(.) match newline
+ PERL, JAVA, and Python
(?s): dot(.) match newline
(?m): ^ match after newline, $ match before newline
+ PERL
(?d), (?l): same as (?u)

Original extensions

+ hexadecimal digit char type  \h, \H
+ named group              (?<name>...)
+ named backref            \k<name>
+ subexp call                  \g<name>, \g<group-num>