Wildcard characters in AutoCAD
Wednesday, July 1, 2026Selecting every object whose layer starts with WALL in one go, showing only your dimension layers, keeping just the blocks whose name ends in _2D… these tasks come up constantly in AutoCAD. The good news: you don't need to write any code for them. AutoCAD ships with a wildcard engine — close to regular expressions but far simpler — available right in the interface.
In this article we start from the everyday use of a standard user, then work our way up to developer use (AutoLISP and .NET). The key point: it is the exact same engine at every level. The patterns you learn with the mouse can be reused as-is in your scripts.
What does a pattern look like?
A pattern (or filter) is a string in which some characters carry a special meaning. The most common ones:
*stands for any sequence of characters (including an empty one);?stands for a single arbitrary character;#stands for a single digit.
So WALL* means "anything starting with WALL", *_2D means "anything ending in _2D", and PLAN-### means "PLAN- followed by three digits". We'll see the full list further down; let's start by putting them to use.
Quick Select (QSELECT)
Quick Select (the QSELECT command, also available from a right-click in the drawing) lets you select objects based on their properties. When you filter on a text property — the layer name, the block name, some text… — the Matches wildcard operator turns wildcards on.

For example, to select every object on a layer starting with WALL:
- run
QSELECT; - under Property, choose Layer;
- under Operator, choose Matches wildcard;
- under Value, type
WALL*; - confirm: all matching objects are selected at once.
Thanks to the comma, you can even target several families at the same time: WALL*,PARTITION*,COLUMN*.
Searching in the Layer Properties Manager
The Layer Properties Manager (the LAYER command) has a search box in its top-right corner that understands wildcards. Type a pattern to display only the matching layers.

This is perfect for quickly locating a layer in a template that holds hundreds of them.
Layer property filters
One step beyond a simple search: layer property filters. Inside the Layer Properties Manager, they let you create groups that fill themselves automatically based on a pattern. Every layer whose name matches shows up in the filter, including those you create later.

A filter named "Dimensions" based on DIM* will automatically gather DIM, DIM-TEXT, DIM_2D… You then manage the visibility or the lock state of the whole group in a single move.
The same principle (a field that accepts wildcards) appears in many other dialog boxes: managing linetypes, styles, purging named items, and so on.
The full list of wildcard characters
Now that the principle is clear, here are all the special characters AutoCAD recognizes in a pattern:
| Character | Meaning |
|---|---|
# (pound) |
A single numeric digit |
@ (at) |
A single alphabetic character |
. (period) |
A single non-alphanumeric character |
* (asterisk) |
Any character sequence (including an empty one), at the start, middle, or end |
? (question mark) |
A single arbitrary character |
~ (tilde) |
As the first character of the pattern: matches anything except the pattern |
[...] |
Any one of the enclosed characters |
[~...] |
Any single character not enclosed |
- (hyphen) |
Inside brackets: specifies a range of characters |
, (comma) |
Separates two patterns (a logical OR) |
` (reverse quote) |
Escapes the next character (reads it literally) |
These characters work everywhere: in the interface fields shown above just as in the code we now turn to.
For developers: the (wcmatch) function in AutoLISP
Let's move to the programming side. In AutoLISP, this engine is exposed by the (wcmatch string pattern) function. It returns T if the string matches the pattern, and nil otherwise.
(wcmatch "PLAN-001" "PLAN*") ; => T
(wcmatch "PLAN-001" "*001") ; => T
(wcmatch "SECTION-002" "PLAN*") ; => nil
It is the ideal tool to test user input, filter a list of names, validate a code… Let's go through each character.
* — any sequence
The most widely used wildcard. It stands for zero, one, or more characters, in any position:
(wcmatch "WALL_EXT_01" "WALL*") ; => T (starts with WALL)
(wcmatch "WALL_EXT_01" "*01") ; => T (ends with 01)
(wcmatch "WALL_EXT_01" "*EXT*") ; => T (contains EXT)
(wcmatch "WALL" "WALL*") ; => T (the sequence may be empty)
? — any single character
Unlike *, ? matches exactly one character:
(wcmatch "A1" "A?") ; => T
(wcmatch "A12" "A?") ; => nil (two characters after A)
(wcmatch "SIDE" "SI??") ; => T
# — a digit
The # accepts only a digit (0 to 9). Very handy to validate numbered codes:
(wcmatch "PLAN-007" "PLAN-###") ; => T
(wcmatch "PLAN-XYZ" "PLAN-###") ; => nil
(wcmatch "R12" "@##") ; => T (a letter followed by two digits)
@ — a letter
The @ accepts only an alphabetic character. Combined with #, it describes precise formats, such as a registration code or a reference:
(wcmatch "A320" "@###") ; => T
(wcmatch "2320" "@###") ; => nil (starts with a digit)
. — a non-alphanumeric character
The period matches a character that is neither a letter nor a digit (space, hyphen, underscore, punctuation…):
(wcmatch "A-1" "@.#") ; => T (letter, separator, digit)
(wcmatch "A_1" "@.#") ; => T
(wcmatch "AB1" "@.#") ; => nil (B is alphanumeric)
[...] — a set of characters
Brackets define a character set: at that position the string must contain one of the listed characters:
(wcmatch "PLAN" "[PC]LAN") ; => T (P or C)
(wcmatch "CLAN" "[PC]LAN") ; => T
(wcmatch "VLAN" "[PC]LAN") ; => nil
- — a range inside brackets
Inside brackets, the hyphen defines a range:
(wcmatch "C" "[A-F]") ; => T
(wcmatch "M" "[A-F]") ; => nil
(wcmatch "ROOM-5" "ROOM-[0-9]") ; => T
(wcmatch "REV_C" "REV_[A-Z]") ; => T
[~...] — an excluded character
A tilde at the start of the brackets inverts the set: the character must be different from those listed:
(wcmatch "PLANB" "PLAN[~A]") ; => T (the last character is not A)
(wcmatch "PLANA" "PLAN[~A]") ; => nil
(wcmatch "X" "[~0-9]") ; => T (anything but a digit)
~ — global negation
Placed at the very beginning of the pattern, the tilde inverts the whole result: the string matches if it does not match the rest of the pattern:
(wcmatch "SECTION-01" "~PLAN*") ; => T (does not start with PLAN)
(wcmatch "PLAN-01" "~PLAN*") ; => nil
, — several patterns (OR)
The comma lets you test several patterns at once. The function returns T if at least one of them matches:
(wcmatch "SECTION-02" "PLAN*,SECTION*,DETAIL*") ; => T
(wcmatch "FACADE" "PLAN*,SECTION*,DETAIL*") ; => nil
This is ideal to filter on a family of prefixes.
` — escaping a special character
What if you want to search for a character that is itself a wildcard? You escape it with a reverse quote (`). The character that follows is then read literally.
The classic example is AutoCAD's anonymous blocks, whose names start with * (such as *U2). To target the *U2 block exactly, without the asterisk being interpreted as a wildcard:
(wcmatch "*U2" "`*U2") ; => T
(wcmatch "XU2" "`*U2") ; => nil (the literal asterisk is required)
In the same way, to search for a string that really contains a #, a ?, or a comma, you prefix each of those characters with `.
Wildcards in ssget
The most frequent use of (wcmatch) is in fact indirect: it is built into ssget's selection filters. In a filter list, any DXF group code that carries a text value accepts wildcards directly: layer name (code 8), block name (code 2), linetype (code 6), and so on.
Here you don't need to call (wcmatch): AutoCAD applies the engine automatically. It is, in effect, the scripted version of the Quick Select we saw earlier.
Select every object whose layer starts with WALL:
(ssget "X" '((8 . "WALL*")))
Select on several layer prefixes at once thanks to the comma:
(ssget "X" '((8 . "WALL*,PARTITION*,COLUMN*")))
Select every block reference (INSERT) whose name ends in _2D:
(ssget "X" '((0 . "INSERT") (2 . "*_2D")))
Exclude a layer using the tilde (every object except those on the DIM layer):
(ssget "X" '((8 . "~DIM")))
The "X" tells ssget to scan the whole drawing database. You can also drop the "X" to combine these filters with an interactive selection: only the objects matching the pattern are then kept from what the user picks.
The .NET equivalent: WcMatchEx
On the .NET API side, the same engine is exposed — but in an internal namespace, which signals that it is not officially supported and could change. The signature is:
Autodesk.AutoCAD.Internal.Utils.WcMatchEx(string str, string pattern, bool ignoreCase);
It returns a bool and adds a genuinely useful argument: ignoreCase, to compare regardless of case.
using Autodesk.AutoCAD.Internal;
bool m1 = Utils.WcMatchEx("PLAN-007", "PLAN-###", ignoreCase: true); // true
bool m2 = Utils.WcMatchEx("wall_ext", "WALL*", ignoreCase: true); // true
bool m3 = Utils.WcMatchEx("wall_ext", "WALL*", ignoreCase: false); // false
For instance, you can use it to list the layers in a drawing that match a pattern:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Internal;
using Autodesk.AutoCAD.Runtime;
[CommandMethod("LISTWALLS")]
public void ListWallLayers()
{
Document document = Application.DocumentManager.MdiActiveDocument;
Database database = document.Database;
Editor editor = document.Editor;
const string PATTERN = "WALL*,PARTITION*";
using (Transaction transaction = database.TransactionManager.StartTransaction())
{
LayerTable layerTable = (LayerTable)transaction.GetObject(database.LayerTableId, OpenMode.ForRead);
foreach (ObjectId layerId in layerTable)
{
LayerTableRecord layer = (LayerTableRecord)transaction.GetObject(layerId, OpenMode.ForRead);
if (Utils.WcMatchEx(layer.Name, PATTERN, ignoreCase: true))
editor.WriteMessage("\n{0}", layer.Name);
}
transaction.Commit();
}
}
Caution:
WcMatchExlives inAutodesk.AutoCAD.Internal. As its name says, this API is internal and is not guaranteed from one version of AutoCAD to the next. For selection filtering, prefer patterns directly in thessget/SelectionFilterfilters, which remain the official route. ReserveWcMatchExfor cases where you already hold the string (layer name, block name, user input) and want exactly the same wildcard semantics as the rest of AutoCAD.
In summary
AutoCAD's wildcard engine is a thread that ties everyday use to development:
- on the user side, it is there from Quick Select, layer search, and layer filters — no code required;
- on the developer side, you meet it again, identical, in
(wcmatch), in thessgetfilters, and inWcMatchExin .NET.
The key characters: *, ?, #, @ and . cover the essentials; [...], [~...] and - refine character by character; ~ and , build complete filters; and ` escapes the wildcards themselves (think of the *U… anonymous blocks). Learn these patterns once, reuse them everywhere.
Need an AutoCAD (AutoLISP, ObjectARX, .NET, VBA) development? Contact me for a free quote.