---
title: "Parse a full name into first and last names in C#"
url: https://recursiveai.org/onecontact/cookbook/parse-person-name/
description: "Parse a full name into first and last names in C#: runnable OneContact example with real output, matching rules and practical variations."
version: "1.0.0"
---

# Parse a full name into first and last names in C#

**OneContact** is a free, open-source contact data library for .NET from Recursive AI. MIT or Apache-2.0, no native dependencies, no network access.

[NuGet](https://www.nuget.org/packages/RecursiveAI.OneContact) · [GitHub](https://github.com/recursive-ai-oss/onecontact-csharp) · [Docs](https://recursiveai.org/onecontact/docs/) · [Download example (.zip)](https://recursiveai.org/onecontact/cookbook/parse-person-name/parse-person-name.zip)

Split a full name into given, middle and family parts without treating every space as a field boundary.

```shell
dotnet add package RecursiveAI.OneContact
```

Requires [.NET 10](https://dotnet.microsoft.com/download/dotnet/10.0) (net10.0); .NET 9 and earlier aren’t supported.

```csharp
using RecursiveAI.OneContact;
var name = PersonName.Parse(
    "Dr. Jane Alice Smith Jr.");
Console.WriteLine(name.Given);
Console.WriteLine(name.Family);
```

```text
Jane
Smith
```

Unzip [the example](https://recursiveai.org/onecontact/cookbook/parse-person-name/parse-person-name.zip), then `dotnet run`.

## Full program

All sample input is written directly in the program.

```csharp
using RecursiveAI.OneContact;

var name = PersonName.Parse("Dr. Jane Alice Smith Jr.");
Console.WriteLine($"Given: {name.Given}");
Console.WriteLine($"Middle: {name.Middle}");
Console.WriteLine($"Family: {name.Family}");
Console.WriteLine($"Prefix: {name.Prefix}");
Console.WriteLine($"Suffix: {name.Suffix}");
Console.WriteLine($"Canonical: {name.Canonical}");
```

`dotnet run` prints:

```text
Given: Jane
Middle: Alice
Family: Smith
Prefix: Dr.
Suffix: Jr.
Canonical: Dr. Jane Alice Smith Jr.
```

`PersonName.Parse` throws `ContactParseException` for rejected text; ambiguous readings still need review rather than treating a successful parse as certainty.

## Variations

Read a family-first name marked by a comma:

```csharp
using RecursiveAI.OneContact;
var name = PersonName.Parse("Smith, Jane Alice");
Console.WriteLine(name.Given);
Console.WriteLine(name.Middle);
Console.WriteLine(name.Family);
```

```text
Jane
Alice
Smith
```

## Related recipes

- [Deduplicate contacts](https://recursiveai.org/onecontact/cookbook/deduplicate-contacts/)

## The short answer

Use `PersonName.Parse` and read `Given`, `Middle` and `Family`. OneContact also keeps titles, particles, second family names, nicknames and suffixes in separate parts. The snippet at the top prints `Jane` and `Smith`, while the full program shows where `Dr.`, `Alice` and `Jr.` went.

This is a rules-based reading of the supplied text, not a way to discover a person’s identity. The [name parsing documentation](https://recursiveai.org/onecontact/docs/names/) states: “Nothing is inferred: no gender, origin or salutation, and no part is added that the text did not contain.” Keep the original full name if you need to let the person correct the result.

## How do I split a full name into first and last names in C#?

Map `Given` to a first-name field and `Family` to a family-name field only when those fields fit the application. The parser has more parts than that pair because a name can contain more structure. A particle such as `van der` stays in `Particle`, separate from `Family`. A second family name can have its own part. Dropping all other parts just because an export has two columns loses information.

The variation uses a comma to mark family-first input: `Smith, Jane Alice`. The parsed parts are the same given, middle and family names as in given-first input. `Canonical` writes reading order, while `Order` remembers the input order. Canonical text is useful for display, but it is not a replacement for the source when the exact input matters.

A bare single word can be accepted by `PersonName.Parse`, with the `SingleWord` flag. That does not supply a missing surname. Don’t fill an absent family name by copying the given name or by guessing from an email address. The output can only describe what the input supports.

## How do I parse first, middle and last names in C#?

Read `Middle` explicitly instead of appending every word after the first to the family name. The full program shows all three fields from a single synthetic input. Prefixes and generational suffixes are separate again, so they do not have to be manually removed before parsing.

Supply country and language hints with [`NameHints(Region? country, string? language)`](https://recursiveai.org/onecontact/docs/names/#hints) to choose between readings left open by the text. The documented examples include Hungarian family-first order and Spanish-style second family names. A hint never overrules the text. Supply hints from known context, not from the current process culture: OneContact results do not depend on `CultureInfo`.

Casing restoration applies when the whole input is one case. Mixed-case text stays as written. This is a rule-based transformation, not proof that the resulting spelling is the person’s preferred spelling. In an editable form, show the result as a suggestion and preserve a path to correction.

## What are common mistakes when parsing names?

A space split confuses particles, titles, suffixes and compound forms with field boundaries. Assuming every input is one person is another mistake: use [`NameParsing.Classify` and `NameParsing.SplitMany`](https://recursiveai.org/onecontact/docs/names/#classes) to classify the input and split multiple people. For a person field, reject or review text that represents a company or several people instead of silently storing the first chunk.

Comparison is a separate decision. `PersonName.Key` aggressively folds parts and some nicknames; it is not the canonical display name. The [person key notes](https://recursiveai.org/onecontact/docs/name-keys/) document exactly what is lost. Use that key for candidate matching, not to overwrite the name the person supplied.
