Replace Underscores
The one-line fix for Danbooru-style tag prompts
- processed_text
This is the most boring node in the Alchemine pack, and it earns its place. Replace Underscores turns blue_sky_hair into blue sky hair. One input, one output, no settings, no surprises. You'd think that's too trivial to ship as a node - and then you wire up a workflow where half your tags come from a Danbooru-trained tagger and the other half from a plain-text source, and you realize you need a place to normalize them.
Why you'd reach for it
Anime models trained on Danbooru learned a vocabulary where tags are stored with underscores - 1girl, long_hair, blue_sky - and the comma-separated tag style is the native prompting paradigm for that whole family (Illustrious, NoobAI, Pony's e621/Danbooru hybrid). But not every source in your chain speaks that convention. An LLM-based prompt helper might hand you spaces. A caption file might have underscores. The two don't tokenize the same way: CLIP sees blue_sky as one glued token while blue sky splits into words, and which one the model "means" depends on what it saw in training.
So this node is really about consistency. It's also the first stage of the pack's ProcessTags mega-node, which chains ReplaceUnderscores → FilterTags → FilterSubtags → SDXLAutoBreak - the author's own default pipeline for tag prompts.
The honest take: whether underscores or spaces are "correct" depends on the checkpoint, and it's a two-minute A/B test either way. What's never in question is that the rest of your pipeline is easier to build if the choice is made in one place.
How it works
There is no clever mechanism here. The source is a single text.replace("_", " ") - every underscore becomes a space, full stop. That's also why it's predictable: it doesn't try to be smart about tag boundaries or preserve anything, it just normalizes. Give it a string, get the same string with the underscores gone.
Inputs and outputs
- text - the prompt or tag string to normalize.
- processed_text - the underscore-free result, ready for a CLIP Text Encode or the next cleaning stage.
No CLIP, no model, no configuration. Drop it between your tag source and your encoder, or run it standalone on a string you want to inspect.
Installation
It's part of ComfyUI-Alchemine-Pack. ComfyUI Manager: search "Alchemine" and install, then restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/alchemine/comfyui-alchemine-pack
pip install -r requirements.txt
Restart ComfyUI and you're done. The pack's only hard dependency is python-dotenv; nothing in the prompt nodes needs a model download or an API key. The optional .env file only matters for the pack's OpenAI/Grok/Danbooru nodes.
Common issues
The failure modes are mild. If your prompt legitimately contains underscores that aren't tag separators - say, a URL or a file path in the text - they'll get flattened to spaces too; there's no escape hatch. And if your target model actually wants underscores kept (some Danbooru-style workflows deliberately prompt with them intact), this node is a one-way door - put it after a switch or just bypass it. It's cheap enough that the standard pattern is to test the same prompt through it and without it and keep whichever renders better.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| processed_text | STRING | — |