This seems to be a common sort of problem, but I haven't seen an answer that works in Bash directly. What I've got so far, using the case where I want to grab the file name up to the first blank or period, where $f is the filename (e.g., f="filename-fileversion filetype.file-subtype"), is
echo ${f#*[. ]}
which does what I want, but it leaves me with the remainder of the string (filetype.file-subtype) when what I want is the excluded part (filename-fileversion) and
echo ${f%[. ]*}
which gives me the first part of the string, but it matches to the last occurrence of the pattern (filename-fileversion filetype). Variations moving the asterisk before/after the pattern end up returning the entire filename.
Is there a way to do what I want without resorting to an external program?