parseHumanName function

HumanNameParserUtils parseHumanName(
  1. String full
)

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,
  );
}