{{variable}} Works but [variable] Doesn't
Grab prompt templates from all over and you learn that variable notation is different in every tool. Some use {{variable}}, some {variable}, and some docs mark it [variable]. Feed a square-bracket template into the prompt variable extractor and nothing gets extracted — and that's not a bug, it's intended design. Here's why square brackets specifically were left out, dissecting the actual regex structure.
1. Why variable syntax differs by tool
Prompt variable notation has never had a standard. Each ecosystem just brought over its own language's string-substitution syntax. {{variable}} (double curly braces) is the standard in LangChain's PromptTemplate, Jinja2, and Handlebars.js; {variable} (single curly brace) is common in Python's str.format() and f-string family; $variable is used in Python's string.Template and shell script pipelines; percent constructs like {% for %} are used in advanced Jinja2 templates needing loops and conditionals. So "which syntax you use" is also a trace of which framework the prompt passed through.
2. Verifying the supported range from the actual regex
The tool's variable-finding logic is just these two regexes.
/\{\{(\w+)\}\}/g — captures double curly braces/\{(\w+)\}/g — captures single curly braces
The regex itself has no pattern for handling square brackets [ ] at all. So "low recognition rate" is wrong — "not a target of the check in the first place" is the accurate description. Interestingly, the two regexes overlap. The string {{role}} matches the double-brace regex, but the single-brace regex also separately matches the inner {role} part. The reason results aren't duplicated is that the extracted values go into a Set (deduplicating collection), not an array. Even when the two regexes overlap, only one "role" remains in the final result.
3. The real reason square brackets are left out: clash with markdown
The reason square-bracket syntax [variable] wasn't included isn't that it's technically impossible — it's that supporting it dramatically raises the risk of misbehavior. Square brackets are already used in two common text syntaxes.
- Markdown links: in the
[text](URL)format, the bracket contents are the link's display text. - Footnote notation:
[1],[^1]denote reference/annotation numbers.
If [variable] were supported as variable syntax, perfectly fine text like [source](https://example.com) or [1] in a prompt pasted straight from a GPT answer would all be misrecognized as "variables." An input field asking for a value would appear that the user didn't want, and in the worst case the link's display text would be wholesale replaced with something else. So the lack of square-bracket support isn't a performance limitation — it's a deliberate choice to avoid wrongly touching actual text.
4. A misbehavior scenario in numbers
Below is an example of a frequently used meeting-notice prompt. Here's what goes wrong assuming square brackets were also recognized as variables.
| Source | Current (no square-bracket support) | If square brackets were supported |
|---|---|---|
Dear {{name}}, meeting notice | 1 variable: name | 1 variable: name (same) |
For details see [minutes](https://x.com/notes) | No change, link kept as-is | Misrecognized as variable → "minutes" input field created, entering a value breaks the link text |
Check [1] for references | No change, footnote number kept | Misrecognized as variable "1" → if not filled in, the source stays as-is and confuses the user |
As the table shows, there's only 1 real variable, but recognizing square brackets adds 2 more false positives. The false-positive rate in a single prompt spikes to 66% (2 of 3), so not supporting it is the reasonable default.
5. How to name variables safely
The capture group is \w+, and in JavaScript regex \w means [A-Za-z0-9_] — that is, only ASCII letters, digits, and underscore. Non-ASCII letters, spaces, and hyphens (-) aren't included. So a name with a space like {{user name}} breaks the regex at that point and fails to be recognized whole, and a variable name made purely of non-ASCII characters isn't extracted because \w doesn't match those characters. To use it safely, name variables with a combination of ASCII letters, digits, and underscore like {{role}}, {{user_name}}, or if you must use non-ASCII, add an ASCII prefix like {{role1}}.
[..."{{role}}".matchAll(/\{\{(\w+)\}\}/g)] in the browser console and it correctly captures "role"; running it against a non-ASCII-only name returns an empty array [].Frequently Asked Questions
Q. What if I really have to use [variable]?
A. The simplest way is to replace [variable] with {{variable}} or {variable} before pasting. If you're building a template from scratch, use curly-brace syntax from the start.
Q. Can I mix {{variable}} and {variable} in one template?
A. Yes. The two regexes operate independently and results are merged into a Set, so mixing them still extracts everything correctly. For readability, though, standardize on one syntax within a project.
Q. Are syntaxes like $variable or {% %} supported?
A. No. This tool's extraction logic uses only the two regexes for {{variable}} and {variable} — dollar signs and Jinja2 control constructs (loops, conditionals) aren't checked at all. Templates written in other syntax must first be converted to curly-brace form.
Q. If the same variable appears multiple times, do I get multiple input fields?
A. No. Duplicates are removed via a Set, so the input field is generated only once, and entering a value applies it to every position in the template simultaneously.