Laravel aside, your task can be done in just one line/call of preg_replace() in your user-defined function:
return preg_replace('/^([^,]+), (.+?)(?: (I?[VX]|[SJ]R\.|[VX]?I{1,3}))?$/', '$2 $1 $3', $name);
Regex Demo Link
This will reconstruct the full name strings with optional suffixes including SR., JR., and Roman numerals from 1 to 13 (that should be sufficient).
Pattern Breakdown:
^ # Match from the start of the string ([^,]+) # Capture all characters until a comma is found , (.+?) # Match a comma and a space, then lazy capture one or more characters (?: ( # Match a space then capture qualifying matches to follows... I?[VX] # Match: IV, V, IX, X | # or [SJ]R\. # Match: SR. or JR. | # or [VX]?I{1,3} # Match: I, II, II, VI, VII, VIII, XI, XII, XIII ) # )? # make the capture group optional (so suffix is not required) $ #Match to end of the string
In my PHP demo, I'll add a consideration for flagging unsuccessful reconstruction attempts via a shorthand conditional in the return line.
PHP: (Demo)
function reconstructName($name) { $name = preg_replace('/^([^,]+), (.+?)(?: (I?[VX]|[SJ]R\.|[VX]?I{1,3}))?$/', '$2 $1 $3', $name, 1, $count); return $count ? $name : "*** Name Reconstruction Failed: $name"; // handle failures as/if you wish } $registry = ["MILLERS, WALTER M IV", "DUPONTE, THOMAS B. II", "HARDIWAY, GRANT U. SR.", "GUIDRY, PAUL JOHN", "BLAH", "FIVERSON-O'FIFE, FIVEY V.", "FIVERSON, FIVEY V", "FIVERSON, FIVEY V V", "O'FIVERSON, FIVEY V. V", "THREE-TRIP, THERESA III", "JUNIPER, JUNE JR.", "VENDETTA, V. V. V", "CÔTÉ, ZOË", "SLEVIN, LUCKY N. VII" ]; foreach ($registry as $name) { echo reconstructName($name) . "\n"; }
Output:
WALTER M MILLERS IV THOMAS B. DUPONTE II GRANT U. HARDIWAY SR. PAUL JOHN GUIDRY *** Name Reconstruction Failed: BLAH FIVEY V. FIVERSON-O'FIFE FIVEY FIVERSON V FIVEY V FIVERSON V FIVEY V. O'FIVERSON V THERESA THREE-TRIP III JUNE JUNIPER JR. V. V. VENDETTA V ZOË CÔTÉ LUCKY N. SLEVIN VII
Some Closing Notes:
- My method will require a substring before the comma, then a substring following the space after the comma.
- A suffix is not required. A suffix must qualify as one of the valid substrings, or else it will considered part of the "given names" portion.
- Notice the pattern will permit apostrophes, hyphens, and foreign characters.
- The
preg_replace() limit parameter is set to 1 as there will not possibly be more than one. - While not a Laravel solution, I think it is compelling to use this single, native php function. The pattern only really gets a little crazy when adding in the suffix considerations.
- The pattern allows
I to mean SR.. This seems appropriate since you were allowing II and JR.. - A
V. will never qualify as a Roman numeral; only a V at the end of the string will qualify.