批量文本替换
Find and replace across a whole batch of prompts
- TEXTS
Sooner or later a batch workflow generates twenty prompt variants, and you realise every one of them says masterpiece, best quality - a phrase you removed from your template three weeks ago and which does nothing useful on a modern model anyway. Editing twenty strings by hand isn't the job you signed up for. 批量文本替换 (QG_TextReplace) runs up to three find/replace rules across a string list and hands you the list back.
How it works
Two ways in. Wire a text list into texts and every item gets processed. Or leave it unwired and type a single string into text - the box is always there and always optional, so the node works as a one-off rewriter too. If you connect nothing at all it raises with a clear message rather than quietly emitting an empty list.
Up to three rules: find1/replace1, find2/replace2, find3/replace3. An empty find string skips that rule, so you can use rule 2 without inventing a dummy rule 1.
The clever-and-occasionally-annoying part is how each pattern is interpreted. The node tries to compile your find string as a regular expression, and if it compiles, that's what it uses. If it doesn't compile - unbalanced brackets, a trailing backslash - it falls back to a literal string replacement. Replacements support backreferences like \1 when the pattern was a regex.
Rules apply in order, and later rules see earlier rules' output. So you can normalise in step one, extract in step two, and rewrite the extraction in step three.
Inputs and outputs
texts(optional, wildcard STRING) - the batch; a single string connected here is treated as one item.text(optional, multiline STRING) - used whentextsisn't connected.find1/replace1…find3/replace3(optional, STRING) - three rules, empty find = skip.- Output
TEXTS(STRING, declared as a list) - the result, in input order.
That output is a list, which is what makes it composable with the rest of the text group - chain it into 文本按分隔符分割, or into another replace node if three rules aren't enough, since nothing stops you stacking them.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/live1617/ComfyUI-QG-tools
Full restart; look for [QG-tools] v0.9.2 加载完成 | 节点数 24. Manager search ComfyUI-QG-Tools where the registry entry is published. Zero dependencies - the pack's requirements file is comments-only on purpose so Manager has no pip step, and this node is pure Python string work.
Ported from ComfyUI_Muye (MIT). Search replace, find replace, batch text or 文本替换.
Where people get burned
Accidental regex. This is the one. find values like 1.5, (masterpiece), a+b or a comma-separated tag list all compile as valid regular expressions and therefore behave as patterns, not text. 1.5 matches 155 - the dot is "any character". If you mean a literal, escape it: 1\.5, \(masterpiece\), a\+b. There's no "treat as literal" switch, so escaping is the skill.
Sandwiching the pattern in anchors. A pattern that matches too much is usually greedy, not broken - .* will swallow across a whole line. Non-greedy .*? plus a literal stop character is the usual fix.
Order matters more than you think. Rule 3 operating on rule 1's output is a feature until it surprises you: chained rules can produce a value neither of them was written with alone. Build them one at a time and check the output.
Empty list, not an empty string, when nothing comes through. If the list arrives empty, you get an empty list out - the node doesn't invent a placeholder. Anything downstream that assumes at least one item will then fail somewhere less obvious.
The prompt-engineering angle is worth a line: mass-editing prompts is how people discover their template was carrying dead weight. The KB's notes on prompt drift are the context here - if a find/replace pass keeps having to strip the same tokens, the tokens don't belong in the template.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| textsopt | STRING | 接文本列表(接单条字符串也会被当成一条处理) | |
| textopt | STRING | 没有接 texts 时用这里的文本 | |
| find1opt | STRING | 规则 1 的查找内容(留空跳过);能编译成正则就按正则处理 | |
| replace1opt | STRING | 规则 1 的替换内容(正则里可用 \1 反向引用) | |
| find2opt | STRING | 规则 2 的查找内容(留空跳过) | |
| replace2opt | STRING | 规则 2 的替换内容 | |
| find3opt | STRING | 规则 3 的查找内容(留空跳过) | |
| replace3opt | STRING | 规则 3 的替换内容 |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| TEXTS | STRING | 替换后的文本列表(顺序与输入一致)。 |