Регулярные выражения для названия города

Мне нужно регулярное выражение для проверки текстового поля города, поле текстового поля города принимает только буквы, пробелы и тире (-).


person Manaysah    schedule 01.08.2012    source источник
comment
Какой язык программирования вы используете?   -  person Andrew Logvinov    schedule 01.08.2012
comment
Я пытался много раз. но ни одна из моих попыток не увенчалась успехом.   -  person Manaysah    schedule 01.08.2012


Ответы (13)


Это может быть сколь угодно сложным, в зависимости от того, насколько точным вам нужно совпадение, и от вариации, которую вы готовы разрешить.

Что-то довольно простое, например ^[a-zA-Z]+(?:[\s-][a-zA-Z]+)*$, должно работать.

предупреждение: это не соответствует таким городам, как Мюнхен и т. д., но здесь вам в основном нужно работать с частью выражения [a-zA-Z] и определять, какие символы разрешены для вашего конкретного случая. .

Имейте в виду, что это также позволяет использовать что-то вроде Сан-Франциско или иметь несколько пробелов.

Переводится примерно так: 1 или более букв, за которыми следует блок из: 0 или более пробелов или тире и более букв, этот последний блок может встречаться 0 или более раз.

Странные вещи там: бит ?:. Если вы не знакомы с регулярными выражениями, это может сбить с толку, но это просто означает, что часть регулярного выражения в круглых скобках не является захватываемой группой (я не хочу захватывать ту часть, которая соответствует ей, чтобы повторно использовать ее позже), поэтому круглые скобки используются только для группировки выражения (а не для фиксации совпадения).

"New York" // passes

"San-Francisco" // passes

"San Fran Cisco" // passes (sorry, needed an example with three tokens)

"Chicago" // passes

"  Chicago" // doesn't pass, starts with spaces

"San-" // doesn't pass, ends with a dash
person pcalcao    schedule 01.08.2012
comment
+1, но ваш [\s-]* должен быть [\s-]+. Эта часть регулярного выражения не должна становиться активной, если не виден фактический символ дефиса или пробела. - person Alan Moore; 01.08.2012
comment
Вы совершенно правы, нет смысла иметь город, оканчивающийся пробелами или тире, и это было бы разрешено моим текущим регулярным выражением, изменив его... Спасибо! - Обновлено: на самом деле изменено только на [\s-], так как я не думаю, что нам нужны несколько пробелов или хифенов без следующих букв. - person pcalcao; 01.08.2012
comment
Если вы хотите, чтобы такие города, как Мюнхен, были пропущены, замените [a-zA-Z] на \p{L} Вот моя версия: ^\p{Lu}\p{L}*(?:[\s-]\p{Lu}\p{L}*)*$ - person Philippe Hebert; 22.11.2016
comment
Как насчет [0-9]? Это справедливо и для названий городов. - person ; 10.09.2019
comment
Что, если я хочу, чтобы он начинался с пробела (или нескольких пробелов)? - person Milkncookiez; 05.05.2020
comment
Для объяснения того, что означает \p{L}, есть хороший ответ здесь: stackoverflow.com/questions/14891129/ - person Pete; 02.06.2021

Этот ответ предполагает, что буквы, на которые ссылается @Manaysah, также включают использование диакритических знаков. Я добавил одинарную кавычку, поскольку она есть у многих имен в Канаде и Франции. Я также добавил точку (точку), поскольку она требуется для сокращенных имен.

Основываясь на ответе @UID, который я придумал,

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

Список городов, которые он принимает:

Toronto
St. Catharines
San Fransisco
Val-d'Or
Presqu'ile
Niagara on the Lake
Niagara-on-the-Lake
München
toronto
toRonTo
villes du Québec
Provence-Alpes-Côte d'Azur
Île-de-France
Kópavogur
Garðabær
Sauðárkrókur
Þorlákshöfn

И что он отвергает:

A----B
------
*******
&&
()
//
\\

Я не добавлял использование скобок и других знаков, так как это не входило в рамки этого вопроса.

Я держался подальше от \s для пробелов. Табуляция и перевод строки не являются частью названия города и, на мой взгляд, не должны использоваться.

person Community    schedule 05.09.2014
comment
^([a-zA-Z€-ɏ]+(?:(\. )|-| |'))*[a-zA-Z€-ɏ]*$ должно быть (\. ) вместо просто . , так как . это особый персонаж - person maxisam; 25.02.2016
comment
Я заменил последний. с +, чтобы запретить название города, заканчивающееся дефисом - person mattlary; 30.03.2017
comment
Это не работает, если город содержит номер... например NICE CEDEX 1 - person V. Sambor; 13.09.2017

Добавляю свой ответ, если он кому-то нужен при поиске Regex для названий городов, как и я.

Пожалуйста, используйте это:

^[a-zA-Z\u0080-\u024F\s\/\-\)\(\`\.\"\']+$

Поскольку многие названия городов содержат тире, например Soddy-Daisy, Tennessee, или специальные символы, такие как ñ в Ла-Каньяда-Флинтридж, Калифорния

Надеюсь это поможет!

person UID    schedule 24.10.2013
comment
При дальнейшем тестировании это регулярное выражение также принимает () // --- и другие. - person ; 05.09.2014

Вот тот, который я нашел, работает лучше всего

для разновидностей PCRE, позволяющих \p{L} (.NET, php, Golang)

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

для регулярного выражения, которое не позволяет \p{L} заменить его на [a-zA-Z\u0080-\u024F]

поэтому для javascript используйте регулярное выражение python

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

Внести в белый список кучу символов легко, но есть вещи, на которые нужно обратить внимание в регулярном выражении.

  • последовательные неалфавитные символы не допускаются. т. е. Los Angeles должно завершиться ошибкой, потому что в нем есть два пробела
  • периоды должны иметь пробел после. т. е. St.Albert должен потерпеть неудачу, потому что в нем отсутствует пробел
  • имена не могут начинаться или заканчиваться небуквенными символами, т. е. -Chicago- не должен
  • символ пробела \s !== \, т. е. может передаваться символ табуляции и перевода строки, поэтому вместо него следует определить символ пробела

Примечание. При построении правил регулярных выражений я нахожу https://regex101.com/tests очень полезно, так как вы можете легко создавать модульные тесты

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

person Daniel    schedule 09.05.2018
comment
Работая с Golang, я нашел ваше регулярное выражение более чем полезным! _Иисус благословит тебя - person dilungasr; 20.01.2021

Вот тот, который будет работать с большинством городов и был протестирован:

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

Код Python ниже, включая его тест.

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
person charlax    schedule 05.07.2019

^[a-zA-Z\- ]+$

Также это может быть полезно http://www.cheatography.com/davechild/cheat-sheets/regular-expressions/

person BSen    schedule 01.08.2012
comment
Это будет работать только для английских имен. München (Мюнхен) не подходит. Вместо этого может помочь использование \w, если использовать его с осторожностью. - person amon; 01.08.2012
comment
amon, \w поймать цифры и _ - person burning_LEGION; 01.08.2012
comment
@burning_LEGION Вот тут-то и возникает осторожность. В Perl я бы написал /((?!\d|_)[\w -])+/ (упреждающий) - person amon; 01.08.2012
comment
ваше регулярное выражение лучше, чем любое в этом посте =) - person burning_LEGION; 01.08.2012

используйте это регулярное выражение:

^[a-zA-Z-\s]+$

person burning_LEGION    schedule 01.08.2012
comment
\s разрешает любые пробелы, а не только пробелы. - person mogelbrod; 01.08.2012
comment
Да, вероятно, лучше всего объявить символ пробела `` вместо \s, как если бы текстовое поле допускало многострочное, оно будет анализировать символ новой строки как действительный. - person GoldBishop; 05.08.2013

После многих часов поиска сопоставления регулярных выражений городов я создал его, и он на 100% соответствует моим потребностям.

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

выражение для тестирования города. Матчи

  • Город
  • Санкт-Сити
  • Какой-то глупый город
  • Городская ул.
  • Город слишком много слов

кажется, что есть много разновидностей регулярных выражений, и я создал это для своих нужд в Java, и оно отлично работает

person Monkey Wrench    schedule 18.06.2018
comment
это позволит - & точка в конце - person Satish Patro; 08.05.2020

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

Это поможет определить названия некоторых городов, таких как Сент-Джонс, Бэ-Сент-Энн, Гранд-Салют/Гранд-Фолс.

person prafful24    schedule 17.09.2018
comment
точка должна быть рядом с \s- ^[a-zA-Z.-]+(?:[\s-.][\/a-zA-Z]+)*$, иначе точка будет стоять в конце - person Satish Patro; 08.05.2020

Мне нравится предложение Шепли, но в нем есть пара недостатков.

Если вы измените регулярное выражение shpeley на это, оно не будет принимать другие специальные символы:

^([a-zA-Z\u0080-\u024F]{1}[a-zA-Z\u0080-\u024F\. |\-| |']*[a-zA-Z\u0080-\u024F\.']{1})$

person Brandon L    schedule 20.08.2015

Я использую тот:

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

Вы можете попробовать это:

^\p{L}+(?:[\s\-]\p{L}+)*

Приведенное выше регулярное выражение будет:

  • Ограничение начальных и конечных пробелов, дефисов
  • Сопоставьте города с такими названиями, как Невиллер-пре-Лотербург.
person Nitin Khanna    schedule 26.08.2014
comment
Следует отметить, что это вариант регулярного выражения php и golang, js и python должны использовать \u0080-\u024F вместо \p{L} - person Daniel; 09.05.2018

Вот несколько забавных крайних случаев:

  • Гравленд
  • Гравендел
  • Гравенполдер
  • Гравензанде
  • 's Heer Arendskerke
  • Херенберг
  • Херенгук
  • Хертогенбос
  • 'т Хард
  • т Вельд
  • 'т Занд
  • 100-мильный дом
  • Город 6 октября

Итак, не забудьте добавить ' и 0-9 в качестве возможного первого символа названия города.

person Maxim Mazurok    schedule 22.06.2020