Hi Nicholas. To fully accomplish this task with 100% success, you need nothing short of magic. Now, I'm only being partially ironic here, since to anyone that doesn't have a full grasp of our language (such as a regular expression), parts like III or Jr. are in no way discernible from an actual last name. I mention this exact case in my conference presentation of patterns as one of the most common and unfortunate limitations of regular expressions.
That said, not all hope is lost. There are some things you can do here, but it might not cover every possible case if one comes up that you don't expect. I'd call this fairly advanced pattern matching. To handle all the cases here, we'd need to basically create a bunch of expectations and combine them with a bunch of "ors", to create a fairly complex regex. Note that I will make a few assumptions here, the biggest being that the name of the person is the entire input and the only input, meaning the first character is the M in "Mike" and that the end of the person's name is the end of the input.
(If you want to skip all the explanation, use the last regex for one which should work in most cases, though I can't guarantee any regex is 100% perfect here).
To handle the Jr. case, you can basically tell it that the part you need does not end with a period... and that it might (potentially) be followed by a word that contains a period. That is handled by this component:
\s(\w+[^\s.])(?:\s\w+\.)?$
The "$" is important here because it lets us start from the end of the input (that is, it makes sure that the pattern up to the $ happens directly before the invisible last character in the input, indicated by $).
So, based on that, it's "a space, then one or more word character, then a final character that is neither a space nor a period (capture these 2 parts as the last name), then optionally the grouping of a space, one or more word characters, plus the period. Note that with just this pattern you can correctly capture "Mike Jones Jr." or "Mike Jones Jr" where the bold one is the one actually captured. This means the period indicates the particular part that is NOT a last name. It also means "Jr" is treated as an actual last name, in the absence of a period.
For the III we have to do something potentially trickier. We need to basically know it's coming. We can then specifically design a match that will handle that exact case. We do it by putting the III there explicitly:
\s(\w+[^\s.])\sIII$
We need to do this explicitly because III is "special". There is no way for the regex to otherwise know that it's not actually a last name.
Now we need to put this one together with the other one. We can group up each regex without capturing by using the grouping operator (?: ), and we will "join" the expressions using the "or" operator, |. We end up with this monster
(?:\s(\w+[^\s.])(?:\s\w+\.)?$)|(?:\s(\w+[^\s.])\sIII$)
This regex will get "Jones" for each case you've provided above. It even handles "John Quincy Jones Jr." However, it does not handle "John Quincy Jones IV". For that you need to generalize for the possible Roman numerals in some way, such as:
(?:\s(\w+[^\s.])(?:\s\w+\.)?$)|(?:\s(\w+[^\s.])\s[VIXM]+$)
That should handle generations of Mike Jones =)
We can actually regroup this regex associatevly to make it potentially easier to understand part-by-part:
\s(\w+[^\s.])(?:(?:\s(?:(?:\w+\.)|[VIXM]+)))?$
This has 2 parts, the latter of which can be split into another 2 parts:
\s(\w+[^\s.]) (?:(?:\s(?:(?:\w+\.)|[VIXM]+)))? $
\s(\w+[^\s.]) (?:(?:\s (?:(?:\w+\.) | [VIXM]+ )))? $
Part one basically says there is a space before the last name, and that you are capturing one or more word characters followed by exactly one character that is neither a space nor a period. Here you are capturing "Jone" and then "s".
Part two basically says there is an bit which might optionally appear (designated by that '?' at the end). It always starts with a space. Then it's one of 2 things. Option 1 is one or more word characters ending with a period (for Jr., Sr., etc), and Option 2 is one or more of the characters VIXM.
Finally, we reach the end of the input.
Note that this will not work for a "full" name such as "Prince".
And there you have it. The final regex is
\s(\w+[^\s.])(?:(?:\s(?:(?:\w+\.)|[VIXM]+)))?$
This should cover all the cases you presented, plus other cases like "Mike Quincy Jones Jr.", "Mike Jones Sr.", "Mike Jones IV", "Mr. Jones", etc. It will NOT cover cases like "Mike", or "Mike Jones " (note the extra space), though this is easily remedied with an extra \s*. Hope this helps you =).