【问题标题】:Regular Expressions for City name城市名称的正则表达式
【发布时间】:2012-08-01 10:08:29
【问题描述】:

我需要一个正则表达式来验证城市文本框,城市文本框字段只接受字母、空格和破折号(-)。

【问题讨论】:

  • 你使用什么编程语言?
  • 我试过很多次了。但我的尝试都没有成功。

标签: regex city


【解决方案1】:

此答案假定@Manaysah 所指的字母也包含变音符号的使用。我添加了单引号 ' 因为加拿大和法国的许多名字都有它。我还添加了句点(点),因为它是合同名称所必需的。

基于我想出的@UIDs 答案,

^([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 的空白。制表符和换行符不是城市名称的一部分,我认为不应使用。

【讨论】:

  • ^([a-zA-Z\u0080-\u024F]+(?:(\.)|-| |'))*[a-zA-Z\u0080-\u024F] *$ 它应该是 (\. ) 而不仅仅是 ". ",因为 .是一个特殊字符
  • 我替换了最后一个 .使用 + 表示不允许以连字符结尾的城市名称
  • 如果 city 包含一个数字,这将不起作用...例如“NICE CEDEX 1”
  • 在我看来是最好的答案。
【解决方案2】:

这可以任意复杂,具体取决于您需要匹配的精确程度以及您愿意允许的变化。

^[a-zA-Z]+(?:[\s-][a-zA-Z]+)*$ 这样相当简单的东西应该可以工作。

警告:这与慕尼黑等城市不匹配,但在这里您基本上需要使用表达式的 [a-zA-Z] 部分,并定义允许使用的字符你的特殊情况。

请记住,它还允许像 San----Francisco 之类的东西,或者有多个空格。

翻译为: 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

【讨论】:

  • +1,但您的 [\s-]* 应该是 [\s-]+。除非看到实际的连字符或空白字符,否则正则表达式的该部分不应变为活动状态。
  • 你是完全正确的,城市以空格或 hifens 结尾是没有意义的,而我当前的正则表达式允许这样做,改变它......谢谢! - 更新:实际上已单独更改为 [\s-],因为我认为我们不需要多个空格或 hifens 而无需跟随字母。
  • 如果您希望像慕尼黑这样的城市通过,请将[a-zA-Z] 替换为\p{L} 这是我的版本:^\p{Lu}\p{L}*(?:[\s-]\p{Lu}\p{L}*)*$
  • [0-9] 怎么样?这在城镇名称中也有效。
  • 如果我想让它以一个空格(或多个空格)开头怎么办?
【解决方案3】:

如果有人在搜索城市名称的正则表达式时需要我的答案,就像我做的那样

请使用这个:

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

由于许多城市名称包含破折号,例如 Soddy-Daisy, Tennessee,或特殊字符,例如 ñ in La Cañada Flintridge, California

希望这会有所帮助!

【讨论】:

  • 在进一步测试中,这个正则表达式还接受 () // --- 和其他。
【解决方案4】:

这是我发现效果最好的一个

对于 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
php:https://regex101.com/r/Yo3GV2/1/tests

【讨论】:

  • 使用 Golang,我发现您的正则表达式非常有用! _耶稣保佑你
【解决方案5】:

这是一种适用于大多数城市的方法,并且已经过测试:

^[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

【讨论】:

    【解决方案6】:

    【讨论】:

    • 这仅适用于英文名称。 München(慕尼黑)不匹配。谨慎使用时,使用\w 会有所帮助
    • amon, \w 捕捉数字和_
    • @burning_LEGION 这就是要小心的地方。在 Perl 中我会写 /((?!\d|_)[\w -])+/(前瞻)
    • 你的正则表达式比这篇文章中的任何一个都好=)
    【解决方案7】:

    使用这个正则表达式:

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

    【讨论】:

    • \s 将允许任何空格,而不仅仅是空格。
    • 是的,最好实际声明空格字符 ` ` 而不是 \s 好像文本框允许多行,它会将换行符解析为有效。
    【解决方案8】:

    在寻找城市正则表达式匹配器数小时后,我构建了它,它 100% 满足我的需求

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

    测试城市的表达式。 匹配

    • 城市
    • 圣。城市
    • 一些愚蠢的城市
    • 城市街
    • 城市话太多

    似乎有很多种正则表达式,我为我的 Java 需求构建了它,它工作得很好

    【讨论】:

    • 这将允许 - & 点在末尾​​span>
    【解决方案9】:
    ^[a-zA-Z.-]+(?:[\s-][\/a-zA-Z.]+)*$
    

    这将有助于识别一些城市名称,例如 St. Johns、Baie-Sainte-Anne、Grand-Salut/Grand Falls

    【讨论】:

    • 点应该在 \s- ^[a-zA-Z.-]+(?:[\s-.][\/a-zA-Z]+)*$ 附近,否则它将允许点在末尾​​span>
    【解决方案10】:

    我喜欢 shepley 的建议,但它有几个缺陷。

    如果你把 shpeley 的正则表达式改成这个,它不会接受其他特殊字符:

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

    【讨论】:

      【解决方案11】:

      我用那个:

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

      【讨论】:

        【解决方案12】:

        你可以试试这个:

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

        上述正则表达式将:

        • 限制前导和尾随空格、连字符
        • 匹配名称为 Néewiller-près-lauterbourg 的城市

        【讨论】:

        • 应该注意这是php和golang正则表达式的味道,js和python应该使用\u0080-\u024F而不是\p{L}
        【解决方案13】:

        这里有一些有趣的边缘案例:

        • 的墓地
        • 的墓地
        • 的墓地
        • 的墓碑
        • 's Heer Arendskerke
        • 的海伦伯格
        • 的 Heerenhoek
        • 的海尔托亨博斯
        • 不难
        • 't Veld
        • 不是赞德
        • 百里之家
        • 6 October City

        所以,不要忘记添加'0-9 作为城市名称的可能第一个字符。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-04-01
          • 1970-01-01
          • 2014-01-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多