Nodes/ComfyUI-Pixaroma/Text Match Pixaroma
ComfyUI Node

Text Match Pixaroma

The model said 'Yes.' — now turn that into a filter you can wire

By pixaroma·Created 7 months ago·Updated about 16 hours ago· 463
Text Match Pixaroma
  • value
  • match
  • index
  • word
  • if_match
  • if_no_match
◄text—►
◄wordsyes►
◄modecontains any word►
◄ignore_casetrue►
◄whole_wordstrue►

Here's a workflow everyone eventually wants: put a vision model in front of a folder of images, ask it "Is the face sharp? Answer yes or no", and keep only the ones it said yes to. The model cooperates. The graph doesn't, because a text answer is a dead end - nothing downstream can branch on it.

Text Match Pixaroma is the adapter. Text in, a yes/no out, plus two gates that let a picture (or a prompt, or a latent) through only on a match or only without one.

How it works

Matching is literal, and that's a deliberate choice. Every word you type is escaped before use, so your list can never be read as a regular expression - no surprise metacharacters, no runaway patterns. Four modes:

  • contains any word (the default) - at least one of your words is in the text
  • contains all words - every one of them is
  • is exactly one of them - the whole text is one of your words, with surrounding spaces, full stops and quotes ignored, so Yes. and "Yes" and **Yes** all count. This is the one you want after an LLM, because an LLM answering "yes" almost never types just yes.
  • starts with one of them

You get ignore_case (on by default, so Yes and YES and yes are the same) and whole_words (also on by default). Whole-word matching is subtler than it sounds, and in a good way: it's implemented as "not glued to another letter", not as the usual word-boundary marker. That distinction is what lets cat match the filename 01_Cat - a normal word boundary fires between an underscore and a letter, the pack's rule doesn't. Since filenames are a main use case here, that's the difference between working and not.

The gates are the real feature. Behind the scenes they use ComfyUI's own execution blocker: a closed gate means everything downstream of it simply doesn't run. No error, no warning, no red box. That's the mechanism that turns a per-image yes/no into a whole-folder filter in a single Run.

Inputs, outputs, and the recipe

text is the thing being checked - an AI answer, a prompt, a filename (it's an input socket, so you wire it; you can't type into it). words is your list: one per line, or comma separated, and the first one is number 1. mode, ignore_case and whole_words are as above.

The optional value input is where the trick lives. Wire a picture into it and the two gates pass that picture; leave it unwired and the gates pass the text itself.

[Vision model: "Is the face sharp? Answer yes or no."] -> text
                                        words: yes
                                        value: <the IMAGE>
                                            |
                            if_match ---------+--> Save Image Pixaroma

Five outputs: match (a boolean), index (which word matched, 1 for the first in your list, 0 for none), word (the word itself), and the two gates if_match / if_no_match. Wire the gates to whatever comes next; match and index wire nicely into a Save node's filename or a Show Text so you can see what the model actually said.

Because this is a list node when fed a list, it runs once per item - so each picture is gated on its own answer, not on some aggregate. That's what makes the folder filter work.

Traps

"Nothing downstream ran" is the feature working. If a gate is closed, the run continues silently and your save node just doesn't fire. Beginners read that as a broken workflow. Check match on the node before you go hunting for a bug.

Whole words is on. You look for blurry, the model writes "the image is blur", no match. Turn whole_words off if you want partial hits.

Don't put an Image Grid after a gate. A grid needs the complete list to build, so if any single picture was held back, the whole grid is skipped. Wire the grid before the gate.

On a very old ComfyUI, one without the execution blocker class, the gates can't close - the node passes the value both ways rather than failing your Run, and match still tells the truth. Rare now, but that's why a filter might look like it isn't filtering.

Installing

ComfyUI Manager, search Pixaroma, Install, restart. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/pixaroma/ComfyUI-Pixaroma

No models, and nothing beyond the pack's one declared dependency (imageio-ffmpeg, for its video nodes) - this node is pure Python logic and costs nothing to run.

The pack is a solo effort from the designer behind Pixaroma (@pixaroma on YouTube, support over the Pixaroma Discord - GitHub issues and PRs are closed on purpose), and it's bundled in ComfyUI Easy Install on Windows. As with every node in it: if things look broken right after an update, Ctrl+Shift+R the browser tab before you debug anything.

Category👑 Pixaroma/🔀 Logic & Flow

Inputs (6)

NameTypeDefaultDescription
textSTRINGThe text to check, for example an AI Prompt answer, a prompt or a file name.
wordsSTRINGyesThe words or phrases to look for: one per line, or separated by commas. The first one is number 1 for the index output.
modeCOMBOcontains any wordcontains any word = at least one of them is in the text. contains all words = every one of them is. is exactly one of them = the whole text is one of the words (spaces, full stops and quotes around it are ignored, so 'Yes.' counts as yes). starts with one of them = the text begins with one of the words.
ignore_caseBOOLEANtrueOn: Yes, YES and yes are the same.
whole_wordsBOOLEANtrueOn: a word only counts on its own, so 'cat' does not match 'category'. Off: it may be part of a longer word.
valueopt*Optional. Anything to let through only on a match (if_match) or only without one (if_no_match): a picture, a prompt, a latent. Not wired: the gates pass the text.

Outputs (5)

NameTypeDescription
matchBOOLEANTrue when the text matches your words, False when it does not.
indexINTThe number of the word that matched (1 for the first word in the list), 0 when none did.
wordSTRINGThe word that matched, or nothing.
if_match*The value (or the text) when it matches. Without a match nothing after it runs.
if_no_match*The value (or the text) when it does NOT match. With a match nothing after it runs.