Split a postal address into fields with an explicit country. Free-text parsing is available for the supported countries, not every country for which the library knows address fields and formatting rules.
dotnet add package RecursiveAI.OneContactRequires .NET 10 (net10.0); .NET 9 and earlier aren’t supported.
using RecursiveAI.OneContact; var address = PostalAddress.Parse( "123 Main St, Springfield, IL 62704", Region.US); Console.WriteLine(address.Locality);
SpringfieldUnzip the example, then dotnet run.
Free-text parsing supports the United States (including Puerto Rico, the US Virgin Islands, Guam, American Samoa, the Northern Mariana Islands and the US Minor Outlying Islands), Canada, Mexico, Australia, the United Kingdom (plus Jersey, Guernsey and the Isle of Man), Austria, Belgium, Croatia, Czechia, Denmark, Estonia, Finland, France, Germany, Hungary, Ireland, Italy, Latvia, Lithuania, Luxembourg, Malta, the Netherlands, Poland, Portugal, Romania, Slovakia, Slovenia, Spain, Sweden, Switzerland, Norway, Iceland, Liechtenstein, Andorra, Monaco, San Marino and Vatican City, plus French Guiana, Guadeloupe, Martinique, Réunion and Mayotte. This is the documented free-text coverage; knowing a country’s field layout does not mean its free-text parser is available.
Full program
The download includes a fuller example with invented input embedded in Program.cs:
using RecursiveAI.OneContact; var address = PostalAddress.Parse( "123 Main St, Springfield, IL 62704", Region.US); Console.WriteLine(address.StreetLines[0]); Console.WriteLine(address.Locality); Console.WriteLine(address.AdminArea); Console.WriteLine(address.PostalCode);
dotnet run prints:
123 MAIN ST Springfield IL 62704
Rejected text makes TryParse return false; Parse throws ContactParseException when it cannot parse the address.
Variations
Handle unrecognized address text without an exception:
using RecursiveAI.OneContact; if (PostalAddress.TryParse("not an address", Region.US, out var address)) Console.WriteLine(address.Canonical); else Console.WriteLine("Address not parsed");
Address not parsedRelated recipes
- Extract contact information from HTML in C#
- Parse a URL in C#
- Get the domain from a URL in C#
- Format a postal address by country in C#
The short answer
Use PostalAddress.Parse(text, country) to split a supported free-text address into fields. The snippet at the top passes Region.US and prints the locality; the full program also prints the street, administrative area and postal code. For imported or user-entered text that may fail, use the TryParse variation.
An explicit country supplies context for interpreting the address. A short street or postal code is not enough to reliably determine a country. Version 1.0 uses rules; it refuses text those rules cannot read rather than providing a trained-model fallback. The address documentation distinguishes free-text parsing from the structural layer.
How can I parse an address into its individual components in C#?
Read StreetLines, Locality, AdminArea and PostalCode from the parsed value. These names avoid assuming that every country has a US-style city and state. Street lines are a collection, not one universal street string. The full program indexes the first line only because its supplied input is a single-street-line example.
The input on this page is invented and included directly in the program. Notice that the returned street is 123 MAIN ST, not an exact copy of the input capitalization. Parsing can standardize recognized address elements. Keep the source text too when your application needs an audit trail or wants a person to compare the parsed result with what was submitted.
Consult the supported-country list above before accepting free text for a new region; formatting known fields and parsing free text have different coverage.
Use the boolean TryParse overload with an explicit region. It returns false on a rejected value, as the variation shows for not an address. Do not read fields from the output value after failure or silently substitute an empty address into a customer record.
For an import interface, preserve the original row and let the user correct it or enter fields manually. The detailed parsing overloads return ParseDetail for callers that need reason codes. Unsupported free-text countries report address.free-text-refused; text without enough country evidence is a different problem from text that is malformed for a known country.
How do I standardize a Canadian address?
using RecursiveAI.OneContact; var address = PostalAddress.Parse("123 Main St, Toronto ON M5V 2T6", Region.CA); Console.WriteLine(address.Canonical);
123 MAIN ST, TORONTO ON M5V 2T6Use Region.CA when the text is Canadian rather than attempting to interpret it as a US address first. The country selects the rules and the expected roles of the province and postal code. The United States and Canada rules describe what the parser standardizes in those countries.
Keep parsing, structural checks and deliverability as separate decisions. Validate() checks an address against country structure, including required fields and postal-code patterns. It does not consult a postal delivery database. A well-formed address that does not exist can pass. Neither successful parsing nor an empty validation-issue list establishes that a resident or business receives mail there.
If your application already has separate address fields, construct the address with PostalAddress.Create instead of joining fields into a guessed string and parsing them again. That avoids discarding information merely to recover it through free-text rules.