Architect regexp_replace dropping area code on +1XXXXXXXXXX format

Stuck on a regex replacement in Architect. Trying to convert a source number +1XXXXXXXXXX to (XXX) XXX-XXXX for a downstream IVR. The standard regexp_replace function seems to be eating the area code or returning null on specific inputs.

Here’s the expression:

regexp_replace(data.phoneNumber, "^\\+1(\\d{3})(\\d{3})(\\d{4})$", "(\\1) \\2-\\3")

It works fine in my local test harness with Node.js, but inside Architect, it returns the original string untouched if there’s any whitespace or if the + isn’t strictly at the start. I’ve tried escaping the + differently and stripping whitespace first with trim(), but the logic feels brittle.

Is there a known quirk with how Architect handles the ^ anchor or unicode digits in these expressions? The docs are pretty thin on edge cases for phone normalization. Just looking for a more reliable pattern that won’t break on minor formatting variations in the incoming CDR data.

Right, the issue here is almost certainly how Architect handles backslashes inside those double-quoted strings. It’s a bit of a pain, but you usually have to escape the backslash twice for the regex engine to actually see it as a special character.

If you look at the documentation for regexp_replace in the expression builder, it treats the pattern and replacement as standard strings first. So \1 becomes just 1 before the regex engine even gets its hands on it. That’s why the area code disappears or the whole thing returns null.

You’ve got two ways to fix this. The cleaner one is using single quotes for the replacement string, which tends to be more forgiving with escape sequences in this specific function.

regexp_replace(data.phoneNumber, "^\\+1(\\d{3})(\\d{3})(\\d{4})$", '($1) $2-$3')

Notice I switched to $1, $2, etc. in the replacement. Architect’s implementation of this function follows the POSIX style for replacements, not the PCRE \1 style. Mixing those up is a classic gotcha.

If you really need to stick with double quotes for some reason, you’d have to double-escape everything, which makes the expression look like a mess:

regexp_replace(data.phoneNumber, "^\\\\+1(\\\\d{3})(\\\\d{3})(\\\\d{4})$", "(\\1) \\2-\\3")

But honestly, just use the single-quote version with $ references. It’s much easier to read and less likely to break when you copy-paste it into a different flow step later.

Also, double-check that data.phoneNumber isn’t coming through with leading spaces or other whitespace. The ^ anchor is strict. If there’s a space before the +, the match fails completely. You might want to wrap the whole thing in a trim() just to be safe, like regexp_replace(trim(data.phoneNumber), ....

It should sort itself out once you swap those back-references for dollar signs.