Nodes/ControlFlowUtils/🔠 String ⁄ List Operations
ComfyUI Node

🔠 String ⁄ List Operations

One node for 27 kinds of string and list surgery

By VykosX·Created 2 years ago·Updated 2 years ago· 147
🔠 String ⁄ List Operations
  • input
  • aux1
  • aux2
  • aux3
  • output
  • result
operation
start_from_end
case_insensitive
param1
param2
param3

🔠 String ⁄ List Operations is the swiss-army knife of this pack, and honestly the node you'll probably reach for most. It's one node that does 27 different string and list manipulations - split, join, replace, slice, find, count, case-convert, random picks, comparisons - so instead of stacking five nodes from five different packs to process a filename or a prompt, you set one dropdown. It's not a replacement for a proper text-processing pack; it's the thing that stops you from needing one for 90% of what comes up in a generation workflow.

How it works

You give it an input (any type), pick an operation from the dropdown, and it hands you two outputs: output (the value after processing) and result (the verdict, index, or count). The result semantics change per operation, and that's the one thing that trips people up - read on.

Every operation runs through the same plumbing. start_from_end flips direction (prepend instead of append, last occurrence instead of first, reversed lists). case_insensitive makes case-sensitive ops - comparisons, find, replace, start/ends-with - ignore case via casefold, so "FLUX" matches "flux". The mechanism underneath is plain Python, and it shows: SLICE is literally Python slice notation, negative indexes and all.

The one real quirk to understand: you have two ways to feed an operation its arguments. The aux1/aux2/aux3 slots accept any type (wire a number, a list, whatever). The param1/param2/param3 text boxes are string-only but take priority - if a param is non-empty, it overrides the corresponding aux slot. So for quick string arguments you type them in; for non-string arguments (like an integer count) you wire the aux slot.

The inputs that matter

  • input (required, *) - the string or list you're processing.
  • operation (required, 27 choices) - everything else is flavor.
  • start_from_end, case_insensitive (required, booleans).
  • aux1–3 (optional, any type) and param1–3 (optional, strings) - per-operation arguments.

Operations you'll actually use

  • SPLIT / SPLIT_LINES - break a string into a list by a delimiter or by lines. The workhorse for parsing prompts and wildcards.
  • JOIN - the reverse: glue a list into a string with a separator.
  • REPLACE - substring swap, per element for lists.
  • SLICE - cut out a range with Python slice notation (negative values work).
  • FIND - get the index of a substring; -1 if absent. Wire the result into a condition to ask "is this string in there?"
  • LENGTH - count characters or elements.
  • CONCATENATE - glue two or more strings/lists together.
  • TRIM_SPACES / STRIP - clean up whitespace or specific characters off the ends.
  • LOWERCASE / UPPERCASE / PROPERCASE - fix messy model names and tags.
  • RANDOM_INPUT / RANDOM_ELEMENT - pick a random prompt from a list, or a random line. Great for variation batches.

Beware the semantics of result. COMPARE doesn't return a simple boolean - it returns a binary sum (1 if aux1 matches, 2 if aux2, 3 if both, 7 if all three). GENERATE, REPLACE, GET_LINE return True/False for success. SLICE and SPLIT return a length. Most operations leave output unchanged when they're pure tests (like IS_NUMERIC or STARTS_WITH), so check which output actually carries your answer before wiring blind. And TO_STRING will raise an error if it can't convert - it doesn't fail gracefully.

Why it's worth having

Every serious workflow eventually needs to munge text: extract a checkpoint name from Model Selector output, build a save filename, parse a LoRA trigger list, pick a random prompt per iteration. This node folds all of that into one place, and it chains - feed one output into the next node's input and you can build fairly elaborate text pipelines without touching a single other pack. If you're pairing it with this pack's IF selector and Universal Switch, you can even do string-driven branching: test a filename with ENDS_WITH, feed the boolean into a condition, and route whole workflow sections from text.

Install and gotchas

Same as the rest of the pack - no Python dependencies:

cd ComfyUI/custom_nodes
git clone https://github.com/VykosX/ControlFlowUtils

or ComfyUI Manager → search ControlFlowUtils → install → restart.

Two real-world gotchas. First, the 27 options are a lot to stare at; if an operation's semantics are fuzzy, the author's own tooltips on each aux/param slot describe what that operation needs. Second, remember the param-overrides-aux priority - if you have a stale value in a param box, it'll silently override the wire you attached to the aux slot. When something "doesn't do what I wired it to do," check the param boxes first.

Category🐺 VykosX-ControlFlowUtils

Inputs (10)

NameTypeDefaultDescription
input*Input String or List to process
operationCOMBOOperation to perform on the Input
start_from_endBOOLEANWhether to evaluate from the start or the end of the expression
case_insensitiveBOOLEANIgnore case sensitivity for operations that support it
aux1opt*Auxiliary Input 1 (Purpose varies based on operation)
aux2opt*Auxiliary Input 2 (Purpose varies based on operation)
aux3opt*Auxiliary Input 3 (Purpose varies based on operation)
param1optSTRINGWill be used instead of Aux1 if not empty (Purpose varies based on operation)
param2optSTRINGWill be used instead of Aux2 if not empty (Purpose varies based on operation)
param3optSTRINGWill be used instead of Aux3 if not empty (Purpose varies based on operation)

Outputs (2)

NameTypeDescription
output*The Input value after being processed by the chosen operation
result*Result of the chosen operation