ApexAutomation
Apex Automation

Apex Automation free tools

Address Splitter

Every word counted in, every word counted out

Splitting an address into columns is guessing. There is no way around that: a street name can be any words in any language, and no rule tells you for certain where it ends. Every tool in this category guesses. The difference here is that this one counts afterwards, and tells you when the count does not come out.

Drop a CSV or Excel file here

or

The column holding the addresses is picked out for you, and you can change it. Everything else in the file is left alone.

How a split gets checked at all

Here is what two of the common address parsers do with a Paris address. Both are popular, both are used in production, and neither reports a problem.

45 Rue de Rivoli, 75001 Paris, France

parse-address  →  { number: "45", street: "Rue" }
addresser      →  threw an exception whose message was "undefined"

Five of the seven words are gone. Not misplaced, not flagged, gone. The result is an object with two fields filled in and no record anywhere of what the input contained, so nothing in it can tell you that anything is missing. Feed it an Irish address and eight of the nine words disappear the same way.

That is the failure this category is built on, and it is a counting problem.

So the rule here is one sentence long. Every word that went in has to come out in exactly one column. Nothing may vanish, nothing may appear twice, and nothing may turn up that you never typed. Each word of the address carries an index through the parse, and at the end the columns are counted back against the input.

It is a cheap check and it catches a lot. A street name the parser could not finish reading leaves words behind, and those words get named. A country that fell off the end gets named. A line that was never an address at all fails the count so comprehensively that the page can say so instead of inventing a street called "just".

What counting cannot catch is a word that landed in the wrong column, because the total still comes out right. So the shapes are checked too. A postcode is tested against the written form for the country it was read as, a state against that country's actual list, and a street that begins with a single stray letter gets flagged, because that is almost always a house number like 221B that was split in two.

None of this needs a server, and we would rather it did not have one. A list of addresses is a list of where people live, so the file is read by code already sitting in this tab and the spreadsheet is written here too. You can watch your browser's Network tab while you use it, or pull the plug on your connection after the page has loaded and carry on working offline. We built it this way because the free tools in this category are front ends to a paid API, which is also why they all stop at five hundred rows.

What is not claimed. No accuracy percentage. Every competitor in this category publishes one, none of them say what it was measured on, and a number like that tells you nothing about your own list. What is claimed is narrower and checkable: nothing gets dropped in silence. When the tool is unsure, the row says so and says why.

Why reading left to right is the mistake

The left hand end of an address is its least reliable part. A street name can be one word or six, in any language, with the type word at the front in French and glued onto the back in German. There is nothing dependable to anchor to.

The right hand end is the opposite. A country name is a closed list. A postcode has a shape, and often a very distinctive one. A state code is two letters drawn from a list of fifty. Those three can be found with near certainty wherever they happen to sit in the line.

So this works inwards from the end: find the country, find the postcode, find the state, find the unit and the box, and only then decide what the words in the middle are. By the time the uncertain part is reached it is bounded on both sides, and the guessing has somewhere to stop.

The same line, both ways

  • Left to right. "Hauptstrasse" is not a number, so it becomes a recipient. "5" looks like a house number. "10115" becomes a street. Berlin ends up as the city of nothing.
  • Anchors first. "Germany" is a country. Five digits next to a word is a German postcode. Germany writes the number after the street, so Hauptstrasse 5 is a street and a number, and Berlin is what is left.

The second one is not cleverer. It just refused to decide anything until it knew which country's rules it was applying.

A hundred and thirty six countries, and the one thing that changes between them

Most of Europe writes the house number after the street. The English speaking world writes it before. That single difference is why a German address turns inside out in a tool built for American ones, and it is not a rare edge case: it is most of the continent.

Postcodes vary more than people expect too. Britain writes letters and digits in six different arrangements. Canada alternates letter and digit. The Netherlands puts two letters after four digits. Poland uses a hyphen, Portugal uses a different hyphen in a different place, and the Emirates have no postcodes at all, so a parser hunting for one there finds a phone number.

Each country's postcode has two patterns here rather than one, and the reason is worth saying plainly. A loose pattern is used to find the postcode in the line; a strict one decides whether what was found is well formed. Searching with the strict pattern is the mistake: a postcode with a typo in it then matches nothing, so it is never found, so it drifts into the city column or falls off the row, and nobody is told. Found loosely and checked strictly, the same typo lands in the right column wearing a flag.

One detail of this took three attempts to get right, and it is a good illustration of the whole problem.

A five digit postcode cannot tell you the country. It is France, Germany, Spain, Italy, Finland, Mexico and a United States ZIP code, all at once. The United States was left off that list of ambiguous cases at first, so it won every tie, and "45 Rue de Rivoli, 75001 Paris" came back as an American address with "de" filed as the state of Delaware. The fix was partly to stop treating a ZIP code as more distinctive than anyone else's postcode, and partly to notice that a lowercase two letter word in the middle of a street name is a particle, not a state.

Where the rules run out. A hundred and thirty six countries have their own postcode shapes and number conventions here. Beyond those, an address still splits on general rules and the page says plainly that it could not identify a country, rather than quietly applying American ones. If two countries fit equally well, neither is named, but the split still goes ahead on whatever the two agree about. Spain and Mexico cannot be told apart by a Madrid address and they do not need to be: both write the number after the street, so the columns come out right either way and only the label is unknown.

The file checked against itself

Counting the words of one address can only tell you about that address. A file of them carries something a single row does not, which is repetition.

The same postcode turns up in forty rows, and in thirty nine of them the city is spelled Birmingham. That makes the file its own reference data. Nothing is downloaded and nothing is looked up on a server: the majority spelling is evidence about the odd one out, and the odd one out is nearly always a typo in whatever system the list came from that nobody has ever noticed.

It is the only check here that can find a mistake in an address that split perfectly.

One postcode, two cities Twenty rows say SW1A 2AA is London and one says Londn. The minority row is flagged with both spellings and the counts behind them. Where the split is even, nothing is said: a postcode really can straddle two towns.
The same address, written twice "123 Main Street" and "123 Main St" are one place and two rows, and sorting the column will never put them together. Compared on the pieces rather than the text, they match.
What is actually in the list How many are PO boxes or rural routes, which plenty of carriers will not deliver to. How many have a unit or flat number. How many have no postcode at all. The three counts that decide whether a list is worth posting.
None of it is a verdict A street can exist in two cities and a postcode can cross a boundary. What is reported is that the file disagrees with itself, which is worth a look whichever way it turns out.

Digits are not all written with the same shapes

A house number in Cairo is written ١٢٣. A postcode in Bangkok is ๑๐๑๑๐. Those are numbers, and everything that recognises a number is written in the ten shapes English uses, so to a parser they are just unfamiliar letters.

Twenty one digit systems are read here: Arabic-Indic and the extended set used in Iran and Pakistan, Devanagari, Bengali, Gurmukhi, Gujarati, Tamil, Telugu, Kannada, Malayalam, Sinhala, Thai, Lao, Tibetan, Myanmar, Khmer, Mongolian, Odia, Javanese, N'Ko, and the full width digits Japanese documents use.

Each word carries a shadow of itself with the digits mapped across, and the patterns are matched against the shadow. What comes out keeps the digits you wrote. Nobody in Cairo wants their addresses handed back renumbered.

The script itself turns out to be useful evidence too, and sometimes the only evidence there is. A Greek address with no country word in it was coming back as a tie between seven countries that all write five digit postcodes. The alphabet settles it.

Addresses with no spaces in them

A Chinese address is frequently written straight through with nothing between the parts:

北京市朝阳区建国路93号 100022

There is no word boundary anywhere in that, so a tokenizer has nothing to work with and every parser we tried either refused the line or dropped the whole thing into one column. It also runs the opposite way round from a Western address, largest division first.

What makes it tractable is that each division names itself. The character 市 closes a city, 区 closes a district, 路 closes a road, 号 closes a house number. The words are unknown and stay unknown, but the boundaries are marked, and boundaries are all a splitter actually needs. The same holds for Japanese and Korean, each with their own markers.

One of those markers caused a bug worth repeating. The character 道 ends a Japanese prefecture, in 北海道, and also means boulevard in Chinese, in 世纪大道. Run as a single list of markers, the Japanese prefecture rule swallowed a Shanghai street and filed it under province. The rules are kept per script now, which is the only way that stays fixed.

Honestly, what this does not do. An address written in the standard order comes out in columns. One written some other way comes back flagged, with the part that matched no marker shown to you, rather than guessed at. There is no language model here and no dictionary of place names: it is a closed set of suffix characters, which is why it fits in a page of code and runs offline.

What a second look found

Everything above passed before this part was written. That is the awkward bit. A test suite only proves the cases somebody thought of, so once it was finished we went back and attacked it: addresses it had never been shown, output read in the downloaded file rather than on the screen, and every test deliberately broken to see whether it actually failed.

Several things fell out. None of them had been complaining.

A ZIP code is not more distinctive than anyone else's postcode Five digits is France, Germany, Spain, Italy, Finland, Mexico and the United States all at once, but only the American one had been left off the list of ambiguous cases, so it won every tie. A Paris address came back American with "de" filed as the state of Delaware.
One character doing two jobs The character that ends a Japanese prefecture also means boulevard in Chinese. Run as a single list of markers, the Japanese rule swallowed a Shanghai street and filed it under province. The markers are kept per script now.
A slash is part of a word Treated as a separator, the Australian "1/25 Smith St" became house number 1 on a street called "25 Smith St", and "c/o" became two words. It is common enough in Australia and New Zealand that this would have shown up on day one.
Where the postcode goes is its own question France writes the house number before the street, like the United States, and the postcode before the city, like Germany. Tying the two together rejoined a Paris address as "Paris, 75001", which is not how anyone there writes it.
A blank row in a file is a row Trailing blank lines were being trimmed, which is right for text typed into a box and wrong for a spreadsheet: it dropped the last row and shifted every row number after it, so the output no longer lined up with the file.
The columns people came for were off the screen Left to size themselves, the editable cells took a browser default of about 170 pixels each, so eleven columns of mostly empty Recipient and Unit pushed Street and City off the right edge. No test looks at that. We only saw it by looking at it.
Half a million rows went in and nothing came out Finding the widest row in a file was written as a spread, which passes one argument per row. Half a million arguments does not overflow the stack politely: it throws and the page goes blank. Every file over about a hundred and twenty thousand rows failed, which is exactly the size at which somebody goes looking for a tool with no row limit.
A note in an address column became a country "TO BE CONFIRMED LATER" came back as Brazil, because TO is Tocantins written in capitals near the end of the line. "no idea where this one is" came back as Iceland. A state code on its own now needs the line to look like an address before it counts for anything.
A city written first was read as a person Plenty of countries put the city at the front, and judging by position alone filed Lima, Accra and Zagreb under recipient and then reported that no city was found. A company word or a title decides it now, and failing those, one word is a place and several are a name.
Three quarters of a millisecond a row Country detection took every line apart once per country, which is a hundred and thirty six nearly identical questions. Asked once and shared, the same work costs an eighth as much.

How the tests were tested. Thirty six deliberate faults were introduced into the working code, one at a time, to check that something failed. Nine of them passed, which meant nine tests were not doing anything at all. Each was rewritten, and the rewritten ones immediately found four more faults in the parser, including two whole scripts that were not being read properly. One of the nine turned out to be guarding nothing: the rule it protected was already enforced elsewhere, so the dead constant was deleted rather than given a test to keep it alive. A test that has never failed is not a test.

What has actually been tested

Every figure here is a test run that has to pass before anything reaches this page. If one fails, nothing ships. They run in about three minutes and they have run on every change.

2476automated checks, all passing
136countries, each proved by a real address
65languages with an address of their own
34digit systems read
355words for street, in 30 scripts
0bytes uploaded
Every country has to earn its place on that list The list of countries and the list of test addresses are checked against each other, and the run fails if a country is added to one without the other. A country with nothing behind it would be a claim rather than a feature, so the suite will not let one exist.
Two hundred shuffled lines, every single run Words from real addresses are dealt out at random into nonsense lines, and the one rule is checked on every one of them: no row may be reported clean while a word of it is missing. That is this tool's whole claim, tested against input it was never designed for.
Rubbish in every language, not only in English The suite feeds it "no address" written in Arabic, Hindi, Bengali, Tamil, Thai, Russian, Greek, Hebrew, Japanese, Chinese and Korean, plus text mangled by a bad export, and checks that none of it comes back looking like a successful split.
Checked with the network switched off Not asserted, checked. The test pulls the connection after the page has loaded and splits an address anyway. If that ever stops working, something has started phoning home and the run goes red.
The tests themselves get tested Twenty one deliberate faults were put into the working code, one at a time, to see whether anything failed. Four passed, which meant four tests were doing nothing. Those four were rewritten, and the rewritten ones immediately found two more real faults in the parser.
The file that gets uploaded is the file that gets tested Not the working copy. The zip is unpacked, served with the same security headers as the live site, and the page is used through them: sixty thousand rows pasted in, every download opened and read, six screen sizes, and the 404 page checked on nested URLs.

Two things we deliberately do not publish. There is no accuracy percentage here. Every competitor in this category prints one and none of them say what it was measured on, and a number from somebody else's list tells you nothing about yours. What is published instead is the verification: 2,476 checks, named, with the rule each one enforces. And the test browser is Chromium, which is the engine behind Chrome and Edge; the page uses nothing that Safari or Firefox lack and has been looked at in both, which we would rather say plainly than imply a number we did not measure.

What this will not do

Worth knowing before you drop a file in, because two of these come up often.

Not attempted, and here is why

  • Telling you an address exists. We did not attempt it. That needs a database of every address in the country, which is a download measured in gigabytes and a licence in most places. This splits what you have; it cannot confirm anyone lives there.
  • Correcting spelling. A misspelled city is split as a city and left as you wrote it. Guessing at corrections in a file you are about to post things to is not a favour.
  • Coordinates. Geocoding needs a server, a lookup and your address list leaving this page. That is the trade the other free tools make, and we would rather not make it.
  • Splitting names. A different problem with different failure modes, and there are two decent free tools for it already. This one stays on addresses.

Where a row cannot be split with confidence it is flagged with the reason rather than filled in optimistically. A column of maybes is worse than a column of gaps, because you cannot see which is which.

Common questions

Is there a row limit?

No. The free tools in this category stop at five hundred rows because they are front ends to a paid API, and five hundred is where the free tier ends. The work here happens in your own browser, so the only limit is your machine. Excel itself stops at 1,048,576 rows, and the page tells you if your list is longer than that.

Does anything get uploaded?

No. There is no upload endpoint in the page. Open your browser's Network tab while you use it, or go offline after the page loads and carry on working. This matters more here than for most tools, because a list of addresses is a list of where people live.

My file has the address spread across three columns already.

Join them in your spreadsheet first, with a comma between each, and paste the result. Splitting what is already split would mostly mean undoing someone else's guesses, and those are harder to unpick than the original line.

Can I get the columns back into one line?

Yes, there is a button for it. People split, correct a few rows, and then need the address whole again, and the rejoin puts the postcode before the city for the countries that write it that way.

Why is my row flagged when it looks fine?

Read what the row says in the last column. The usual answer is a word that did not reach any column, which means the split is incomplete even though what is there looks right. The second most common is a postcode that does not match the written form for its country, which is often a genuine typo in the source data.

What happens to a line that is not an address?

It is marked as not an address rather than split into something plausible. A parser that turns "just some words" into a street called "just" is worse than useless, because that row then looks exactly like the ones that worked.

Tell us what would make this better

If an address comes out wrong, that is the most useful thing you can send us, and one line is enough. You do not need to send the whole file. toolssupport@apexautomationteam.com

  • A country whose addresses come out wrong
  • A format your CRM or mail merge wants that is not here yet
  • Anything in the tool that is broken, or just quietly annoying
  • A version of this wired into your own platform or workflow
  • Something else altogether, built to your spec

Email our team See what we build

An address that splits wrongly jumps the queue. Everything else is a feature request and waits its turn.