search named groups
Turn a prompt or filename into a labeled dictionary
- DICT
Regex with named groups is how you stop treating text as one blob and start treating it as a record. This node runs a search with a pattern that has (?P<name>...) groups, and returns a DICT mapping each group name to its captured text. One search, and a filename like portrait_ffhq_1024_seed42.png becomes {"subject": "portrait", "dataset": "ffhq", "res": "1024", "seed": "42"} - real fields you can read, branch on, or look up by key.
That's the entire value proposition, and it's a good one. ComfyUI's DICT type (a custom type this pack implements, with the whole family of dict nodes to consume it) is the closest thing the graph has to a structured record, so "parse a string into a dict" is a genuinely load-bearing operation once you're automating anything with metadata in filenames.
How it works
The mechanism is re.search(pattern, string) followed by match.groupdict(). Three specifics matter:
- It's a search, not a match-all: it returns the first match's named groups. If your string has several records, this node gives you one dict; loop the input or pre-split to get the rest.
- If no match is found, you get an empty dict, not an error. That's deliberate - it makes "did the pattern match" checkable downstream by looking at the dict's length.
- Only named groups (
(?P<name>...)) end up in the dict. Plain(...)capture groups are ignored bygroupdict(). If your dict comes back empty but you're sure the text matched, you almost certainly used unnamed groups.
Inputs and output
string- the text to parse.pattern- the regex with named groups, e.g.(?P<subject>\w+)_(?P<res>\d+).
Output is one DICT. Feed it into this pack's DictGet to pull a specific field by name, or a DictContainsKey to branch on whether a field exists.
Installing it
Ships in the Basic data handling pack by StableLlama:
cd ComfyUI/custom_nodes
git clone https://github.com/StableLlama/ComfyUI-basic_data_handling
Restart, or search "Basic data handling" in ComfyUI Manager. The pack has zero dependencies and no model downloads - stdlib only - so install is a non-event.
Gotchas
- The empty-dict-on-no-match behavior is both feature and trap: it means "no match" is indistinguishable from "match with zero named groups." Check dict length rather than existence if that matters.
- Group names must be valid Python identifiers - no spaces, no leading digits.
(?P<res 1024>...)is a regex error before the node even runs. - Greedy quantifiers will mislabel things:
(?P<subject>.*)_(?P<res>\d+)onportrait_ffhq_1024givessubject = "portrait_ffhq", because.*is greedy and takes everything it can. Be explicit about what each group is allowed to contain.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| string | STRING | — | |
| pattern | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| DICT | DICT | — |