Advanced Text Filter
The text-cleaning node that makes messy LLM output actually usable
- external_text
- processed_text (Target)
- remaining_text
This is the node the whole pack is built around. Advanced Text Filter is a Swiss-army text processor: find-and-replace, extract sections between markers, strip formatting, and - the reason people actually seek it out - clean up raw LLM output before it hits your prompt or your JSON parser.
Here's the scenario it exists for. You run an image-to-text or LLM node, and it hands you back something like:
Here is the description: **A red fox** *in snow*, with extra markdown and a trailing thought.
Feeding that garbage straight into a prompt encoder gives you junk tokens. This node peels it apart: extract what's between ** and **, strip the markdown, remove the newlines, and hand the clean text to the CLIP encoder. The author's own launch post walked exactly this kind of "chaotic log → clean prompt" chain, and the dual-output design is what makes it powerful - more on that in a second.
How it works
One text input, one operation - and seventeen modes. They split into groups:
- Find / Replace / Extract (global):
find and remove,find and replace,find all (extract)- all instances, driven byoptional_text_inputandreplace_with_text. - Split / Between (first match only):
extract between,remove between,extract before/after start text,remove before/after start text- driven bystart_text/end_text. - Cleanup: remove empty lines, remove newlines, strip lines, remove all whitespace.
- LLM utilities: extract a code block (between triple backticks), extract the first JSON object, strip markdown formatting.
batch replace: multiple find→replace rules at once, onefind_text -> replace_textper line in thereplacement_rulesbox. This was a direct community request - the "let me feed a list of dirty words and their fixes" feature - and it's the one you want for img2text workflows where you're normalizing a model's vocabulary.
Turn on use_regex and all the find/split operations take regular expressions (with DOTALL for multi-line matching, which is what you need for JSON blocks). case_conversion normalizes to upper/lower first, and concat_mode can prepend or append an external_text input before processing.
The dual outputs are the actual selling point. processed_text (Target) is the result of the operation; remaining_text is what's left over. Chain the remaining text into another Advanced Text Filter and you get an assembly line - peel off one thing per node until the text is exactly what you want. This is the design the author calls "node chaining," and it genuinely beats one mega-node trying to do everything.
if_not_found is the safety valve: when a pattern doesn't match, return the original text, return empty, or hard-fail with an error. For batch runs where one bad item shouldn't kill everything, return original text is the setting that keeps the queue alive.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/rookiestar28/ComfyUI_Text_Processor.git
pip install -r requirements.txt
Or ComfyUI Manager → "ComfyUI Text Processor" → Install → restart.
Gotchas
The remaining_text behavior changes per operation - sometimes it's the leftover, sometimes the extracted match. Read the tooltip when you wire it up. And remember regex is on a toggle: ( in your find text is a regex group when use_regex is on, and nothing when it's off. If a replacement "isn't matching," that's the first thing to check. Regex newbies: \s+, \d+, and <[^>]*> (strip HTML) cover 90% of cleanup needs.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | Primary text processed by the selected operation. | |
| concat_mode | COMBO | Optionally combine external_text with the primary text before processing. | |
| operation | COMBO | Text filtering, extraction, replacement, or cleanup operation to run. | |
| start_text | STRING | Opening marker used by first-match between, before, and after operations; the marker stays in the remaining side. | |
| end_text | STRING | Closing marker used by between operations; both boundary markers stay in the remaining side. | |
| optional_text_input | STRING | Search text or comma-separated patterns used by find operations. | |
| replace_with_text | STRING | Replacement value used by the find-and-replace operation. | |
| use_regex | BOOLEAN | false | Interpret search or boundary text as regular expressions where supported. |
| case_conversion | COMBO | Optional case conversion applied before matching and processing the target text. | |
| if_not_found | COMBO | return original text | Missing-match policy: original sends preprocessed text to the target, empty sends it to remaining, and trigger error raises. |
| external_textopt | * | Optional upstream value converted to text and combined according to concat_mode. | |
| replacement_rulesopt | STRING | One find_text -> replace_text rule per line for batch replacement. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| processed_text (Target) | STRING | Processed target text produced by the selected operation. |
| remaining_text | STRING | Remaining text or extracted match context, depending on the selected operation. |