Nodes/ComfyUI/Contains Text
ComfyUI Node Runs on cloud

Contains Text

One clean boolean for 'is this phrase in there?'

By Comfy-Org·Created 4 years ago·Updated about 11 hours ago· 130,493
Contains Text
    • contains
    string
    substring
    case_sensitivetrue

    Contains Text (StringContains) asks the most common question in text automation: is this substring inside this string? Yes or no, as a clean boolean you can route. Where Compare Text asks "is the whole thing X," and Match Text asks "does a pattern match," this one asks the dumb, everyday question - "does this prompt mention 'watermark'?" - and answers it without any regex.

    That's its whole appeal: no pattern syntax, no escaping, no flags to reason about. You type the exact phrase and get a boolean. It's the natural building block for conditional workflows - check whether an LLM's output contains a JSON marker before parsing, detect whether a generated filename contains a variant tag, gate a cleanup step on whether a phrase showed up at all. And because it takes two plain strings, it's the node you can wire directly from other text nodes without a second thought.

    How it works

    Under the hood it's Python's substring membership test - substring in string - which is a literal substring search. Important distinction: "cat" matches "concatenate" (it's in there), so this is not word-boundary-aware, and it's not a pattern - a period in your substring matches a literal period. Inputs:

    • string - the text to search in.
    • substring - the text to look for.
    • case_sensitive - defaults to true. Same default as Compare Text, opposite of the regex nodes. If "Dog" never matches when you're searching for "dog," this is why.

    Output: a single BOOLEAN named contains. True if the substring appears anywhere, false otherwise.

    A concrete pattern to steal: you're routing LLM output and the model sometimes returns a refusal instead of a prompt. Check Contains for "I can't" (or "sorry"), and when it returns true, reroute to a retry path instead of feeding the refusal into your CLIP Text Encode and generating nonsense. One boolean, one router, no regex - that's the entire job, done.

    Common issues

    The substring-means-anywhere behavior is the main surprise - searching for "an" matches virtually everything, and searching for a single letter will light up your routing in ways you didn't intend. If you need word-boundary or start/end anchoring, that's Compare Text (Starts With/Ends With) or a regex node's territory. Second: the case-sensitive default, especially if you've been using RegexMatch's case-insensitive default - two adjacent boolean nodes with different defaults is a genuine footgun. And empty substring is an edge: an empty substring technically "is in" every string, so if your substring comes from a possibly-empty upstream node, guard against it or every check returns true. For most "does it mention X" logic, though, this node is the one you'll keep reaching for.

    Categorytext

    Inputs (3)

    NameTypeDefaultDescription
    stringSTRING
    substringSTRING
    case_sensitiveBOOLEANtrue

    Outputs (1)

    NameTypeDescription
    containsBOOLEAN