Regular Expressions for City name

Viewed 51017

I need a regular Expression for Validating City textBox, the city textbox field accepts only Letters, spaces and dashes(-).

13 Answers

Here is the one I've found works best

for PCRE flavours allowing \p{L} (.NET, php, Golang)

/^\p{L}+(?:([\ \-\']|(\.\ ))\p{L}+)*$/u

for regex that does not allow \p{L} replace it with [a-zA-Z\u0080-\u024F]

so for javascript, python regex use

/^[a-zA-Z\u0080-\u024F]+(?:([\ \-\']|(\.\ ))[a-zA-Z\u0080-\u024F]+)*$/

White listing a bunch of character is easy, but there are things to watch for in your regex

  • consecutive non-alphabetical characters should not be allowed. i.e. Los Angeles should fail because it has two spaces
  • periods should have a space after. i.e. St.Albert should fail because it's missing the space
  • names cannot start or end with non-alphabetical characters i.e. -Chicago- should fail
  • a whitespace character \s !== \, i.e. a tab and line feed character could pass, so space character should be defined instead

Note: When building regex rules, I find https://regex101.com/tests is very helpful, as you can easily create unit tests

js: https://regex101.com/r/cgJwc0/1/tests
php: https://regex101.com/r/Yo3GV2/1/tests

Here's one that will work with most cities, and has been tested:

^[a-zA-Z\u0080-\u024F]+(?:. |-| |')*([1-9a-zA-Z\u0080-\u024F]+(?:. |-| |'))*[a-zA-Z\u0080-\u024F]*$

Python code below, including its test.

import re
import pytest


CITY_RE = re.compile(
    r"^[a-zA-Z\u0080-\u024F]+(?:. |-| |')*"  # a word
    r"([1-9a-zA-Z\u0080-\u024F]+(?:. |-| |'))*"
    r"[a-zA-Z\u0080-\u024F]*$"
)


def is_city(value: str) -> bool:
    valid = CITY_RE.match(value) is not None
    return valid

# Tests
@pytest.mark.parametrize(
    "value,expected",
    (
        ("1", False),
        ("Toronto", True),
        ("Saint-Père-en-Retz", True),
        ("Saint Père en Retz", True),
        ("Saint-Père en Retz", True),
        ("Paris 13e Arrondissement", True),
        ("Paris  13e  Arrondissement ", True),
        ("Bouc-Étourdi", True),
        ("Arnac-la-Poste", True),
        ("Bourré", True),
        ("Å", True),
        ("San Francisco", True),
    ),
)
def test_is_city(value, expected):
    valid, msg = validate.is_city(value)
    assert valid is expected

After many hours of looking for a city regex matcher I have built this and it meets my needs 100%

(?ix)^[A-Z.-]+(?:\s+[A-Z.-]+)*$

expression for testing city. Matches

  • City
  • St. City
  • Some Silly-City
  • City St.
  • Too Many Words City

it seems that there are many flavors of regex and I built this for my Java needs and it works great

^[a-zA-Z.-]+(?:[\s-][\/a-zA-Z.]+)*$

This will help identify some city names like St. Johns, Baie-Sainte-Anne, Grand-Salut/Grand Falls

Here are some fun edge-cases:

  • 's Graveland
  • 's Gravendeel
  • 's Gravenpolder
  • 's Gravenzande
  • 's Heer Arendskerke
  • 's Heerenberg
  • 's Heerenhoek
  • 's Hertogenbosch
  • 't Harde
  • 't Veld
  • 't Zand
  • 100 Mile House
  • 6 October City

So, don't forget to add ' and 0-9 as a possible first character of the city name.

Related