parseHumanName function
Simple split: "Last, First Middle" or "First Middle Last". Suffix: Jr., Sr., III, etc.
Implementation
HumanNameParserUtils parseHumanName(String full) {
final String s = full.trim();
if (s.isEmpty) return const HumanNameParserUtils();
// Strip a trailing generational suffix before splitting names, so it never
// gets mistaken for a middle/last token (e.g. "Smith, John Jr.").
final RegExp suffixRe = RegExp(r',?\s+(Jr\.?|Sr\.?|III?|IV|II|I)$', caseSensitive: false);
final String? suffix = suffixRe.firstMatch(s)?.group(1);
final String rest = s.replaceAll(suffixRe, '').trim();
// A comma signals "Last, First [Middle]" order; without one it's natural
// "First [Middle] Last" order, handled by the token split below.
if (rest.contains(',')) {
final List<String> parts = rest.split(',').map((e) => e.trim()).toList();
if (parts.length >= 2) {
return HumanNameParserUtils(
last: parts[0],
first: parts[1],
middle: parts.length > 2 ? parts[2] : null,
suffix: suffix,
);
}
}
final List<String> tokens = rest.split(RegExp(r'\s+'));
if (tokens.isEmpty) return HumanNameParserUtils(suffix: suffix);
if (tokens.length == 1) return HumanNameParserUtils(first: tokens.first, suffix: suffix);
return HumanNameParserUtils(
first: tokens.first,
last: tokens.last,
middle: tokens.length > 2 ? tokens.sublist(1, tokens.length - 1).join(' ') : null,
suffix: suffix,
);
}