BGL has limited string functions but powerful pattern matching. Almost everything you’d want to do to a string — extract part of it, test its shape, replace something — uses a regular expression.
when order.id matches /^EXT-\d+$/ then
set order.custom.tag to "external"
end
Reads as: when the order’s id matches the pattern “EXT-“ followed by digits, tag it as external.
If you’ve never used regex before, the regex cheat sheet at the bottom covers the common building blocks.
Concatenation
Use & to glue strings together:
"Order: " & order.id & " (" & order.status & ")"
order.shipping_address.first_name & " " & order.shipping_address.last_name
Both sides of & must be text. To concatenate a number, cast it first:
"Total: $" & order.subtotal as text
Matching a pattern
The matches operator tests whether a string fits a regex:
when order.id matches /^[A-Z]{3}\d+$/ then ... end
when order.customer_email matches /@example\.com$/ then ... end
when order_line.sku matches /^HAZMAT-/ then ... end
Regex literals are slash-delimited: /pattern/. Inside, you can use any standard regex syntax.
Extracting a piece with named captures
To pull a piece out of a string, use a named capture inside a regex and bind it to a variable using the pipe (|) syntax:
prefix | /^(?<prefix>[A-Z]+)-/ matches order.id
Reads as: match order.id against this pattern, and bind the named group prefix to a variable called prefix.
Once captured, the variable is available wherever an expression can go:
set order.custom.tag to prefix | /^(?<prefix>[A-Z]+)-/ matches order.id
A common pattern: extract on one line, use on the next.
set order.custom.normalized_id to num | /(?<num>\d+)/ matches order.external_id
Replacing text
The replace action substitutes one piece of text for another, using a regex to find it:
set order.id to replace /_/ with "-" in order.id
set order.notes to replace /\s+/ with " " in order.notes
The pattern is replace /pattern/ with "replacement" in <text>. The replacement is a literal string (not another regex).
To use a captured value in the replacement, work with named captures and a session variable:
set $part to part | /^(?<part>\w+)/ matches order.id
set order.custom.normalized to replace /^\w+/ with $part in order.custom.normalized
Iterating regex matches
For every match in a string — not just the first — use the regex form of for:
for /(?<num>\d+)/ in order.notes
print "Found number: " & num
end
Each iteration sets the named capture (here num) to the matched substring.
This is the only way to “split” a string in BGL. To split on a delimiter, capture the non-delimiter parts:
for /(?<part>[^,]+)/ in order.custom.tags
# `part` is each comma-separated value
end
What you cannot do directly
BGL doesn’t have these common string functions, so you’ll work around them with regex:
| Want to… | Workaround |
|---|---|
| Get the length | Often unnecessary — match against a length-bounded pattern with matches /^.{N}$/. |
| Trim whitespace |
replace /^\s+/ with "" in field then replace /\s+$/ with ""
|
| Uppercase / lowercase | Not supported. Use case-insensitive regex with (?i). |
| Substring (positions) | Capture the segment with regex: prefix \| /^(?<prefix>.{5})/ matches field. |
| Split on delimiter | Loop with for /(?<part>[^,]+)/ in field. |
If a workaround is awkward, consider whether the source data could be normalized upstream — sometimes “fix it before it gets to us” is easier than fixing it in a rule.
Regex cheat sheet
| Pattern | Matches |
|---|---|
abc |
The literal text “abc” |
^abc |
“abc” at the start of the string |
abc$ |
“abc” at the end of the string |
\d |
A digit (0-9) |
\w |
A word character (letter, digit, or _) |
\s |
Whitespace |
. |
Any single character (except newline) |
[abc] |
Any one of a, b, or c
|
[^abc] |
Anything except a, b, or c
|
[a-z] |
Lowercase letter |
* |
Zero or more of the preceding |
+ |
One or more of the preceding |
? |
Zero or one of the preceding |
{n} |
Exactly n |
{n,m} |
Between n and m |
(...) |
Group |
(?<name>...) |
Named capture group |
\| |
Either side |
\., \\, \/, etc. |
Literal ., \, /
|
A few useful complete patterns:
| Pattern | Matches |
|---|---|
/^\d+$/ |
A whole string of digits |
/^[A-Z]{3}\d+$/ |
3 capital letters then any number of digits |
/^.+@.+\..+$/ |
A loose email pattern (better one in the snippets reference) |
/^[A-Z]{2}$/ |
Two-letter state or country code |
For more, see your favorite regex reference — Mozilla’s MDN regex docs are good — and test patterns at https://regex101.com/ before pasting them into a rule.
Built-in regex snippets
The code editor ships with snippets for common regex patterns: numbers, n-digit minimums, state-code lists, character repetition, email, phone. Type matches in the code editor and pick from the autocomplete list. See Snippets Reference.
Comments
Please sign in to leave a comment.