Filtering by Assembly Code — using a regular expression (regex)
When a rule applies to a structured set of Assembly Codes, maintaining long inclusion lists becomes inefficient and error-prone.
In those cases, a regular expression (regex) is the preferred solution.
(
/* AssemblyCode regex */
$assemblyCodeRegex := /^(32\.[13][15])$/i;
/* Filter FamilySymbols */
$familySymbols := $[
type = "FamilySymbol"
and $match(values.assemblyCode, $assemblyCodeRegex)
].id;
/* Filter FamilyInstances */
$[
type = "FamilyInstance"
and parent.id in $familySymbols
].{
"id": id,
"type": type,
"name": name,
"parent": parent.id
}
)
What this filter does (plain language)
“Select all placed elements whose family type has an Assembly Code that matches a defined pattern.”
With this regex, the allowed Assembly Codes are:
32.1132.1532.3132.35
Nothing else is included.
Step 1 — define the Assembly Code pattern
$assemblyCodeRegex := /^(32\.[13][15])$/i;
What this regex means
^→ start of string32\.→ literal32.[13]→ either1or3[15]→ either1or5$→ end of stringi→ case-insensitive (included for consistency)
This explicitly matches four valid codes, without listing them individually.
Why use a regex instead of a list
Compared to:
["32.11", "32.15", "32.31", "32.35"]
A regex:
- Expresses the structure of the codes
- Scales cleanly when the pattern expands
- Avoids manual maintenance of long lists
- Reduces copy-paste errors
This is ideal when Assembly Codes follow a clear convention.
Step 2 — filter FamilySymbols using $match()
$familySymbols := $[
type = "FamilySymbol"
and $match(values.assemblyCode, $assemblyCodeRegex)
].id;
Key points:
- Assembly Code is a type property
- Regex comparison is done with
$match(string, regex) - Missing or
nullvalues safely evaluate tofalseThis means missing Assembly Codes are excluded from the scope, not reported. - No invalid data is hidden or corrected here
This step answers:
“Which family types comply with this Assembly Code pattern?”
Step 3 — select instances of those types
$[
type = "FamilyInstance"
and parent.id in $familySymbols
]
This links:
- Instance → FamilySymbol
- FamilySymbol → Assembly Code pattern
Each result represents one placed element of a compliant type.
Important differences vs list-based filtering
| Inclusion list | Regex |
|---|---|
| Explicit values | Pattern-based |
| Very safe | Requires precision |
| Less flexible | Highly flexible |
| Verbose | Compact |
Regex increases expressive power — but also responsibility.
Common mistakes to avoid
Forgetting anchors
/32\.[13][15]/
❌ Over-matches unintended values.
Using in with regex
values.assemblyCode in $assemblyCodeRegex
❌ Invalid — regex must be used with $match().
Making the regex too broad
/^32\./
⚠️ Likely to include unintended Assembly Codes.
When not to use regex
Avoid regex when:
- The allowed values are few and unrelated
- Rule clarity is more important than compactness
- Non-technical users must maintain the rule
In those cases, explicit lists are safer.
Key takeaway
Use regex when Assembly Codes follow a clear structure. Use lists when certainty matters more than flexibility.
Why regex is powerful — a real-world example
So far, we used regex to replace short inclusion lists.
Now let’s look at a realistic industry example where a list would be impractical.
/^(13\.2\d|17\.1[123]|17\.2[0135]|21\.2[01235]|22\.2[0123]|23\.2[0-5]|27\.2[0-6]|28\.[13][0-2]|2[1237]\.2|28\.[13])$/i
At first glance, this looks intimidating. In reality, it is just a compact way of describing many allowed Assembly Codes.
What this regex represents
This single expression replaces dozens of explicit values, such as:
13.20,13.21,13.22, …17.11,17.12,17.1317.20,17.21,17.23,17.2521.20,21.21,21.22,21.23,21.2522.20through22.2323.20through23.2527.20through27.2628.10,28.11,28.12,28.30,28.31,28.3221.2,22.2,23.2,27.228.1,28.3
Writing this as a list would be:
- Long
- Hard to maintain
- Easy to get wrong
How to read this regex (conceptually)
You do not need to read this character by character.
Instead, read it like this:
“Match specific structured groups of Assembly Codes, each group following a predictable numeric pattern.”
Each | separates a group:
13.2x
17.1[1–3]
17.2[0,1,3,5]
21.2[0,1,2,3,5]
22.2[0–3]
23.2[0–5]
27.2[0–6]
28.1[0–2]
28.3[0–2]
21.2, 22.2, 23.2, 27.2
28.1, 28.3
Each group encodes:
- A domain decision
- Not an arbitrary value list
Why regex is superior here
1. Intent is explicit
A regex says:
“These codes follow a pattern.”
A list says:
“These are the values I remembered to include.”
Patterns are harder to forget.
2. Changes are safer
If tomorrow:
23.26becomes valid
You change one character:
23\.2[0-6]
Instead of:
- Searching a long list
- Adding another value
- Risking duplicates or omissions
3. Validation stays predictable
Because the regex is:
- Anchored (
^and$) - Explicit per group
You avoid accidental matches like:
213.2123.20027.29
Which would easily slip through a poorly written list or loose regex.
Important warning: regex is power tooling
Regex is a scalpel, not a hammer.
Used well:
- Rules are compact
- Scope is clear
- Maintenance cost drops
Used poorly:
- You over-match
- You under-match
- Nobody understands the rule anymore
When regex is the right choice
Use regex when:
- Codes are structured
- Rules are derived from standards
- The allowed set follows logic, not coincidence
- The rule is reviewed and owned by technical users
Avoid regex when:
- Values are arbitrary
- Non-technical users must edit rules
- The pattern cannot be explained in one sentence
Best practice when using complex regex
- Always anchor (
^and$) - Group logically (use
|per domain group) - Comment the intent in the rule description
- Test with real data before deploying
- Prefer clarity over cleverness
If you cannot explain what the regex does in plain language, it does not belong in a production rule.
Final takeaway
Lists enumerate values. Regex expresses structure.
Once users grasp this difference, regex stops being scary — and starts being one of the most valuable tools in rule authoring.
Pro tip — use regex101.com to build and test your regex
When working with regex, never write it blindly inside a DAQS rule.
Use this website instead:
Why regex101 is so useful
regex101 allows you to:
- Test your regex live against example values
- See exactly which part matches
- Catch over-matching and under-matching early
- Debug complex patterns step by step
This is especially valuable when:
- Replacing long inclusion lists
- Encoding standards-based code ranges
- Working with regex you didn’t write yourself
Recommended workflow
- Copy real Assembly Code values from DAQS Assist output
- Paste them into the test string field on regex101
- Paste your regex into the regex field
-
Verify:
-
All intended values match
- No unintended values match
- Only then copy the regex into your DAQS rule
Important settings on regex101
- Regex flavour: ECMAScript / JavaScript
- Use anchors (
^and$) - Keep the
iflag only if intentional
JSONata uses JavaScript-style regex, so regex101 is a correct match.
Strong recommendation
If you haven’t tested your regex on regex101, it’s not ready for the Playground — let alone Production.
This habit alone will save you hours of debugging and review cycles.