rfind
Rfind — the 'last time this shows up' search your filenames need
- INT
There's a family of string problems where you don't care about the first match - you care about the last one. Where's the final underscore in a filename? Where's the last . before an extension? Where does the last comma live in a generated list? rfind searches from the right and returns the position of the highest-index occurrence, which is the one that splits the tail off cleanly. It's the reverse-direction sibling of the pack's find node.
The classic use: isolating the extension from a filename. Find the last . with rfind, slice everything before it, and you've got the stem - even for files with dots in the name (my.file.v2.png). Same idea for the last / in a path or the last , in a data line.
How it works
Python's str.rfind(substring, start, end), which searches backward and returns the index counting from the start of the string. If the substring isn't found, it returns -1 - no exception, just a sentinel. The node's wrapper has one deliberate convenience: if you leave end at its default of 0, it treats that as "search to the end of the string" (raw Python's rfind(s, 0, 0) would search an empty slice, which is useless in a UI).
"hello hello".rfind("hello")→6"photo.v2.png".rfind(".")→9"no match here".rfind("z")→-1
Inputs and outputs
Two required inputs:
string- the text to search.substring- what you're looking for.
Two optional:
start-INT, default0. Where to begin searching.end-INT, default0. Where to stop;0means "to the end".
Output is one INT: the index of the last occurrence, or -1 if absent.
Installing it
Part of the Basic data handling pack by StableLlama. ComfyUI Manager, search "Basic data handling", install, restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/StableLlama/ComfyUI-basic_data_handling
Pure Python, zero dependencies, no downloads. Under Basic/STRING in the menu.
Common issues
Remember the index counts from the start of the string, not the distance from the end - rfind searches in reverse but reports a normal forward index. The -1 sentinel is the thing to guard against: if your substring can genuinely be absent, check the result before slicing, or your slice logic will eat the whole string. And note it's an exact, case-sensitive match - .PNG won't match .png. For anything fancier than "find the last literal", you're into regex territory, which this pack handles with a separate module.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| string | STRING | — | |
| substring | STRING | — | |
| startopt | INT | 0 | — |
| endopt | INT | 0 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| INT | INT | — |