h4 - Switcheroo
Find-and-replace for your prompts, up to ten swaps at once
- subject
- clip
- data
- string
- conditioning
H4_Switcheroo is the pack's universal find-and-replace node: feed it a prompt (or any text, JSON, even conditioning) and it'll run up to ten find → replace swaps on it. Want to try "portrait" swapped for "landscape" and "sunset" for "golden hour" in one go, without hand-editing the prompt box and re-running five times? That's the whole job. It's a text-transformation utility with a ComfyUI face.
Its self-description is more dramatic - "The last find-and-replace node you'll ever need" - but it's actually a reasonable little tool, with a couple of genuinely nice touches.
How it works
You give it a subject, set swap_count to how many swaps you want, and fill in the matching find_N / replace_N pairs (there are slots 1 through 10). It walks the pairs in order and does a plain string replacement on the subject.
The interesting part is what it accepts as a subject. The type is *, and the node figures out what it's holding:
- A plain string - the common case: your prompt text.
- JSON (a dict or list) - it serializes, replaces, and hands the structure back, so you can do targeted swaps inside a metadata payload or a context bundle.
- Conditioning - it can even reach into a conditioning object, extract the text, swap, and re-encode it. That's the "universal" bit, though the honest caveat is it's looking for strings buried in the structure, and the node will tell you loudly if you wired in a pure tensor instead.
The modifier toggles are where the power is:
- regex_mode (boolean, default OFF) - ON lets your
findfields be regular expressions (mid-.*,\b\d+\b). This turns it from a simple replacer into a real text-transform tool. - case_sensitive (boolean, default OFF) - whether
Newsandnewsare different. - strip_whitespace (boolean, default ON) - trims accidental spaces around your find/replace entries.
- clip (optional CLIP) - connect your CLIP model and the node can re-encode the result, giving you a ready conditioning output.
Outputs: data (*, the transformed subject in its original form), string (STRING, the text as a plain string), and conditioning (CONDITIONING, only meaningful when a clip is connected).
Installing h4_Live
It ships in the h4_Live pack. ComfyUI Manager: search h4_Live, install, restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/m3rr/h4_Live
Restart. No model files, no pip extras - the pack runs on ComfyUI's stock stack.
Common issues
- swap_count is your on/off switch. Set it to 0 and the node becomes a pass-through - it returns the subject untouched (though it may still encode it if a clip is connected). That's by design, not a bug.
- Empty find fields are skipped. If a
find_Nis blank, that slot does nothing, so you don't have to fill all ten. Fill exactly the number inswap_count. - Order matters. Swaps apply sequentially, so
cat → dogthendog → birdwill not turn "cat" into "bird" - the first swap already changed it. Think through the order when pairs interact. - Conditioning input is the fragile corner. If you wire a conditioning that's really just tensors, the node can't find text in it and will tell you to wire the raw STRING prompt instead. That's the honest boundary of the "universal" claim.
- It's an output node. It always runs (that's the point for a transformer), but remember it sits in a pack whose other logic nodes all share one global loop counter - don't be surprised if it interacts with h4 loop state elsewhere in the same graph.
Inputs (26)
| Name | Type | Default | Description |
|---|---|---|---|
| subject | * | The text, JSON, or data container you want to perform swaps on. | |
| swap_count | INT | 10–10 | How many find/replace operations to perform. |
| clipopt | CLIP | Optional: Connect a CLIP model to enable automatic re-encoding if the subject is a prompt. | |
| case_sensitiveopt | BOOLEAN | false | If ON, 'News' and 'news' are treated as different words. |
| regex_modeopt | BOOLEAN | false | If ON, you can use regular expressions (e.g., 'mid-.*') in the FIND boxes. |
| strip_whitespaceopt | BOOLEAN | true | If ON, accidental spaces at the start/end of your entries are ignored. |
| find_1opt | STRING | Target string for swap #1. | |
| replace_1opt | STRING | Replacement string for swap #1. | |
| find_2opt | STRING | Target string for swap #2. | |
| replace_2opt | STRING | Replacement string for swap #2. | |
| find_3opt | STRING | Target string for swap #3. | |
| replace_3opt | STRING | Replacement string for swap #3. | |
| find_4opt | STRING | Target string for swap #4. | |
| replace_4opt | STRING | Replacement string for swap #4. | |
| find_5opt | STRING | Target string for swap #5. | |
| replace_5opt | STRING | Replacement string for swap #5. | |
| find_6opt | STRING | Target string for swap #6. | |
| replace_6opt | STRING | Replacement string for swap #6. | |
| find_7opt | STRING | Target string for swap #7. | |
| replace_7opt | STRING | Replacement string for swap #7. | |
| find_8opt | STRING | Target string for swap #8. | |
| replace_8opt | STRING | Replacement string for swap #8. | |
| find_9opt | STRING | Target string for swap #9. | |
| replace_9opt | STRING | Replacement string for swap #9. | |
| find_10opt | STRING | Target string for swap #10. | |
| replace_10opt | STRING | Replacement string for swap #10. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| data | * | — |
| string | STRING | — |
| conditioning | CONDITIONING | — |