re.sub (Regex Sub)
Find-and-replace with regex power — the node that cleans up half your text problems
- flags
- result
- count
Most text problems in a ComfyUI workflow aren't "find this" - they're "find this and replace it." OvumReSub is re.sub in node form: swap every occurrence of a pattern for a replacement, with backreference support, and get back both the cleaned string and the number of substitutions made. Strip quality tags out of a prompt, normalize filenames, collapse repeated whitespace, redact a token - this is the node that does the actual editing in the regex family.
How it works
You give it pattern, repl, and string. It replaces the leftmost, non-overlapping matches of pattern in string with repl, and if nothing matches, returns the string unchanged. The repl field supports Python's backslash escapes and backreferences: \1 for the first group, \g<name> for named groups, \n for a newline. That's where the real power lives - you can restructure matched text, not just delete it.
Inputs:
pattern- the regex to match (multiline field).repl- the replacement (multiline field;\1,\g<name>,\nall work).string- text to edit.string_in- optional, overridesstring, accepts a list of strings.flags- RE_FLAGS from the re.compile flags node (default IGNORECASE on).count- max replacements; 0 (default) replaces all.
Outputs:
result- the edited string(s).count- how many substitutions were actually made. This is a quiet gem: acountof 0 tells you the pattern never matched, which is a free validity check.
Why you'd reach for it
Prompt cleanup is the big one: strip (quality:1.2)-style weight syntax, remove negative-tag leftovers, normalize commas. Filename normalization is another - turn My Video - (copy) 2!.mp4 into something loader-friendly with one pattern. And because it's list-aware via string_in, you can run the same cleanup across a whole batch of strings in a single pass.
Installing it
Ships in comfy-ovum. ComfyUI Manager → search "comfy-ovum", or:
cd ComfyUI/custom_nodes
git clone https://github.com/sfinktah/comfy-ovum
Restart, find it under ovum/regex. No model downloads; light pure-Python deps handled by Manager.
The gotcha
The backreference syntax trips people who learned $1 from JS: in Python it's \1 or \g<name>, and you need the replacement escaped properly or the backslash gets eaten before the regex ever sees it. Also remember count defaults to replacing all occurrences - if you only wanted the first one, set count to 1. And if you ever find yourself only caring about how many replacements happened and not the string, the pack's re.subn node is functionally the same thing here.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| pattern | STRING | The regular expression pattern. | |
| string | STRING | The string to search. Used if `string_in` is not connected. | |
| repl | STRING | The replacement string or pattern. | |
| string_inopt | STRING | Input string or list of strings. Overrides `string` widget if connected. | |
| flagsopt | RE_FLAGS | 2 | Regex compilation flags. |
| countopt | INT | 0 | Maximum number of pattern occurrences to be replaced. 0 means replace all. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| result | STRING | — |
| count | INT | — |