? in a wildcard pattern matches any character, so we want . in place of [a-zA-Z0-9:$@#-_./]. Actually, it will match a newline, so probably (.|\n) would be better.
std::regex_error should not be thrown unless we made a programming error; I'd replace the contents of that catch with an assert(false) and abort().
The comment (written by me) // TODO (C++23?) return std::vector(subdirs); is inaccurate. The correct and idiomatic C++23 will be usinguse | std::ranges::to<std::vector>().