Find/Replace Pairs
Stop re-typing the same text fixes
- pairs
- json
- csv
Find/Replace Pairs is the boring half of a two-node trick, and boring is the point. Instead of hand-editing the same string fixes into every prompt box in a workflow, you define your rules once - up to 80 of them - and hand them to the Text Replacer node whenever you need them. If you've ever found yourself replacing underscores with spaces in ten different text nodes because your model's tag syntax demands it, this is the node that kills that chore.
Here's why it works at all: in ComfyUI, text is just data until it hits the text encoder. Everything upstream of a CLIPTextEncode is a plain string you're free to transform, and this pack exists entirely in that no-man's land. No sampler, no model, no weights - just string surgery before the prompt gets conditioned.
How it works
Mechanically it's simple, and it's worth knowing because one quirk falls out of it. The node defines 80 pairs of string inputs (find_1/replace_1 through find_80/replace_80) in Python, then a small JS extension hides everything past pair one and adds the ➕ Add Pair and ➖ Remove Last Pair buttons. So the "80 pairs" limit is real, but it's an input-definition ceiling, not a recommendation - the UI only shows what you've added.
When you run it, the node collects every non-empty find pattern into a list. That matters: a row where you typed a replacement but left find blank is silently skipped, so half-filled pairs can't corrupt your output. What comes out the other side:
- pairs - the
FR_PAIRSobject, the only output you'll normally use - json - a JSON array of
{find, replace, index}objects, handy if you want to inspect what you built - csv - a
find,replaceline per pair, with proper quoting for commas
The inputs that matter
Really just one family: the find_N and replace_N pairs. Each has a text widget and an input connector, and the connector wins - if you link a string into find_1, it overrides whatever's typed in the widget. That's how you'd drive rules dynamically from another node instead of hard-coding them.
The one genuinely useful wiring pattern: pairs out → Text Replacer's pairs in. Because FR_PAIRS is a custom type only this pack knows about, you can't feed it into anything else - that's a feature, it keeps the object from leaking into nodes that'd choke on it.
Installing it
Both nodes ship in the same pack, so one install gets you both. Easiest route is ComfyUI Manager: search "Multi-Replace" and install. Otherwise:
cd ComfyUI/custom_nodes
git clone https://github.com/logicalor/comfyui_multi_replace
Then restart ComfyUI. That's the entire install - this is one of the rare packs whose requirements.txt literally says "no additional dependencies required beyond ComfyUI." No pip installs, no model downloads, nothing heavy. It's pure Python standard library plus a bit of JS.
Where people get burned
This pack has essentially zero community footprint - exact-phrase searches on Reddit come back empty, which is consistent with its tiny impression count. Don't expect tutorials or forum threads; you're on your own, and honestly that's fine for something this small.
The one thing that can actually bite: the add/remove buttons and the show/hide behavior live in the JS extension. If the node ever shows up with all 80 pairs and no Add button, the extension didn't load - hard-refresh the browser and check the console. And if a pair isn't being applied, remember the find field must be non-empty; that's the most common "why is it ignoring my row" cause.
Inputs (160)
| Name | Type | Default | Description |
|---|---|---|---|
| find_1opt | STRING | — | |
| replace_1opt | STRING | — | |
| find_2opt | STRING | — | |
| replace_2opt | STRING | — | |
| find_3opt | STRING | — | |
| replace_3opt | STRING | — | |
| find_4opt | STRING | — | |
| replace_4opt | STRING | — | |
| find_5opt | STRING | — | |
| replace_5opt | STRING | — | |
| find_6opt | STRING | — | |
| replace_6opt | STRING | — | |
| find_7opt | STRING | — | |
| replace_7opt | STRING | — | |
| find_8opt | STRING | — | |
| replace_8opt | STRING | — | |
| find_9opt | STRING | — | |
| replace_9opt | STRING | — | |
| find_10opt | STRING | — | |
| replace_10opt | STRING | — | |
| find_11opt | STRING | — | |
| replace_11opt | STRING | — | |
| find_12opt | STRING | — | |
| replace_12opt | STRING | — | |
| find_13opt | STRING | — | |
| replace_13opt | STRING | — | |
| find_14opt | STRING | — | |
| replace_14opt | STRING | — | |
| find_15opt | STRING | — | |
| replace_15opt | STRING | — | |
| find_16opt | STRING | — | |
| replace_16opt | STRING | — | |
| find_17opt | STRING | — | |
| replace_17opt | STRING | — | |
| find_18opt | STRING | — | |
| replace_18opt | STRING | — | |
| find_19opt | STRING | — | |
| replace_19opt | STRING | — | |
| find_20opt | STRING | — | |
| replace_20opt | STRING | — | |
| find_21opt | STRING | — | |
| replace_21opt | STRING | — | |
| find_22opt | STRING | — | |
| replace_22opt | STRING | — | |
| find_23opt | STRING | — | |
| replace_23opt | STRING | — | |
| find_24opt | STRING | — | |
| replace_24opt | STRING | — | |
| find_25opt | STRING | — | |
| replace_25opt | STRING | — | |
| find_26opt | STRING | — | |
| replace_26opt | STRING | — | |
| find_27opt | STRING | — | |
| replace_27opt | STRING | — | |
| find_28opt | STRING | — | |
| replace_28opt | STRING | — | |
| find_29opt | STRING | — | |
| replace_29opt | STRING | — | |
| find_30opt | STRING | — | |
| replace_30opt | STRING | — | |
| find_31opt | STRING | — | |
| replace_31opt | STRING | — | |
| find_32opt | STRING | — | |
| replace_32opt | STRING | — | |
| find_33opt | STRING | — | |
| replace_33opt | STRING | — | |
| find_34opt | STRING | — | |
| replace_34opt | STRING | — | |
| find_35opt | STRING | — | |
| replace_35opt | STRING | — | |
| find_36opt | STRING | — | |
| replace_36opt | STRING | — | |
| find_37opt | STRING | — | |
| replace_37opt | STRING | — | |
| find_38opt | STRING | — | |
| replace_38opt | STRING | — | |
| find_39opt | STRING | — | |
| replace_39opt | STRING | — | |
| find_40opt | STRING | — | |
| replace_40opt | STRING | — | |
| find_41opt | STRING | — | |
| replace_41opt | STRING | — | |
| find_42opt | STRING | — | |
| replace_42opt | STRING | — | |
| find_43opt | STRING | — | |
| replace_43opt | STRING | — | |
| find_44opt | STRING | — | |
| replace_44opt | STRING | — | |
| find_45opt | STRING | — | |
| replace_45opt | STRING | — | |
| find_46opt | STRING | — | |
| replace_46opt | STRING | — | |
| find_47opt | STRING | — | |
| replace_47opt | STRING | — | |
| find_48opt | STRING | — | |
| replace_48opt | STRING | — | |
| find_49opt | STRING | — | |
| replace_49opt | STRING | — | |
| find_50opt | STRING | — | |
| replace_50opt | STRING | — | |
| find_51opt | STRING | — | |
| replace_51opt | STRING | — | |
| find_52opt | STRING | — | |
| replace_52opt | STRING | — | |
| find_53opt | STRING | — | |
| replace_53opt | STRING | — | |
| find_54opt | STRING | — | |
| replace_54opt | STRING | — | |
| find_55opt | STRING | — | |
| replace_55opt | STRING | — | |
| find_56opt | STRING | — | |
| replace_56opt | STRING | — | |
| find_57opt | STRING | — | |
| replace_57opt | STRING | — | |
| find_58opt | STRING | — | |
| replace_58opt | STRING | — | |
| find_59opt | STRING | — | |
| replace_59opt | STRING | — | |
| find_60opt | STRING | — | |
| replace_60opt | STRING | — | |
| find_61opt | STRING | — | |
| replace_61opt | STRING | — | |
| find_62opt | STRING | — | |
| replace_62opt | STRING | — | |
| find_63opt | STRING | — | |
| replace_63opt | STRING | — | |
| find_64opt | STRING | — | |
| replace_64opt | STRING | — | |
| find_65opt | STRING | — | |
| replace_65opt | STRING | — | |
| find_66opt | STRING | — | |
| replace_66opt | STRING | — | |
| find_67opt | STRING | — | |
| replace_67opt | STRING | — | |
| find_68opt | STRING | — | |
| replace_68opt | STRING | — | |
| find_69opt | STRING | — | |
| replace_69opt | STRING | — | |
| find_70opt | STRING | — | |
| replace_70opt | STRING | — | |
| find_71opt | STRING | — | |
| replace_71opt | STRING | — | |
| find_72opt | STRING | — | |
| replace_72opt | STRING | — | |
| find_73opt | STRING | — | |
| replace_73opt | STRING | — | |
| find_74opt | STRING | — | |
| replace_74opt | STRING | — | |
| find_75opt | STRING | — | |
| replace_75opt | STRING | — | |
| find_76opt | STRING | — | |
| replace_76opt | STRING | — | |
| find_77opt | STRING | — | |
| replace_77opt | STRING | — | |
| find_78opt | STRING | — | |
| replace_78opt | STRING | — | |
| find_79opt | STRING | — | |
| replace_79opt | STRING | — | |
| find_80opt | STRING | — | |
| replace_80opt | STRING | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| pairs | FR_PAIRS | Find/Replace pairs object for use with TextReplacer node |
| json | STRING | JSON representation of the pairs |
| csv | STRING | CSV representation of the pairs (find,replace per line) |