typescript
50 lines · 9 steps
Parsing human names into structured parts
A name splitter that handles suffixes, prefixes, and 'Last, First' ordering before carving out first/middle/last.
Explained by
highlit
1interface ParsedName {
2 first: string;
3 middle: string;
4 last: string;
5 suffix: string;
6}
7
8const SUFFIXES = new Set([
9 "jr", "sr", "ii", "iii", "iv", "v", "phd", "md", "esq",
10]);
11
12const PREFIXES = new Set([
13 "mr", "mrs", "ms", "miss", "dr", "prof", "rev", "sir",
14]);
15
16const normalizeSuffix = (token: string): string =>
17 token.replace(/\./g, "").toLowerCase();
18
19export function splitName(fullName: string): ParsedName {
20 const empty: ParsedName = { first: "", middle: "", last: "", suffix: "" };
21
22 if (fullName.includes(",")) {
23 const [lastPart, ...rest] = fullName.split(",");
24 fullName = `${rest.join(" ")} ${lastPart}`;
25 }
26
27 const tokens = fullName.trim().split(/\s+/).filter(Boolean);
28 if (tokens.length === 0) return empty;
29
30 let suffix = "";
31 const tail = tokens[tokens.length - 1];
32 if (tokens.length > 1 && SUFFIXES.has(normalizeSuffix(tail))) {
33 suffix = tokens.pop()!;
34 }
35
36 if (tokens.length > 1 && PREFIXES.has(normalizeSuffix(tokens[0]))) {
37 tokens.shift();
38 }
39
40 if (tokens.length === 0) return { ...empty, suffix };
41 if (tokens.length === 1) {
42 return { first: tokens[0], middle: "", last: "", suffix };
43 }
44
45 const first = tokens.shift()!;
46 const last = tokens.pop()!;
47 const middle = tokens.join(" ");
48
49 return { first, middle, last, suffix };
50}
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Normalizing tokens against known sets lets you detect suffixes and titles regardless of punctuation or casing.
- 2Peeling recognized pieces off the ends first leaves a clean core to split into first/middle/last.
- 3Guarding each length boundary prevents the parser from crashing on empty or single-token input.
Related explainers
typescript
import { useCallback, useEffect, useRef, useState } from "react"; interface UseResendCooldownOptions { cooldownSeconds?: number;
A resend cooldown hook in React
custom-hooks
timers
state-management
Intermediate
7 steps
python
import datetime from dataclasses import dataclass
Parsing fixed-width records in Python
parsing
generators
dataclasses
Intermediate
8 steps
typescript
import { Injectable, PipeTransform, ArgumentMetadata,
A custom validation pipe in NestJS
validation
dto
recursion
Intermediate
10 steps
rust
use std::collections::HashMap; #[derive(Debug)] pub struct RequestHead {
Parsing an HTTP request head in Rust
parsing
error-handling
iterators
Intermediate
9 steps
php
<?php final class MarkdownParser {
Building a small Markdown-to-HTML parser in PHP
state-machine
parsing
closures
Intermediate
10 steps
typescript
import { CallHandler, ExecutionContext, Injectable,
Recording HTTP metrics with a NestJS interceptor
interceptor
observability
prometheus
Intermediate
5 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/parsing-human-names-into-structured-parts-explained-typescript-3b2e/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.