我需要一个用于验证城市文本框的正则表达式,城市文本框字段只接受字母、空格和破折号(-)。
13 回答
该答案假定@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]+(?:[\s-][a-zA-Z]+)*$
应该可以工作。
警告:这与 München 等城市不匹配,但在这里您基本上需要使用表达式的 [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
如果有人在搜索城市名称的正则表达式时需要它,请添加我的答案,就像我一样
请使用这个:
^[a-zA-Z\u0080-\u024F\s\/\-\)\(\`\.\"\']+$
由于许多城市名称包含破折号,例如田纳西州的 Soddy-Daisy或特殊字符,例如加利福尼亚州拉加纳达弗林特里奇的 ñ
希望这可以帮助!
这是我发现效果最好的一个
对于 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
这是一种适用于大多数城市的方法,并且已经过测试:
^[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
^[a-zA-Z\- ]+$
这也可能有用http://www.cheatography.com/davechild/cheat-sheets/regular-expressions/
使用这个正则表达式:
^[a-zA-Z-\s]+$
经过数小时寻找城市正则表达式匹配器后,我构建了它,它满足我的需求 100%
(?ix)^[A-Z.-]+(?:\s+[A-Z.-]+)*$
测试城市的表达式。火柴
- 城市
- 圣城
- 一些愚蠢的城市
- 市街
- 太多话城市
似乎有多种正则表达式,我为我的 Java 需求构建了它,它工作得很好
^[a-zA-Z.-]+(?:[\s-][\/a-zA-Z.]+)*$
这将有助于识别一些城市名称,例如 St. Johns、Baie-Sainte-Anne、Grand-Salut/Grand Falls
你可以试试这个:
^\p{L}+(?:[\s\-]\p{L}+)*
上述正则表达式将:
- 限制前导和尾随空格、连字符
- 匹配名称为 Néewiller-près-lauterbourg 的城市
我喜欢shepley的建议,但它有几个缺陷。
如果您将 shpeley 的正则表达式更改为此,它将不接受其他特殊字符:
^([a-zA-Z\u0080-\u024F]{1}[a-zA-Z\u0080-\u024F\。|\-| |']*[a-zA-Z\u0080-\u024F\ .']{1})$
我用那个:
^[a-zA-Z\\u0080-\\u024F.]+((?:[ -.|'])[a-zA-Z\\u0080-\\u024F]+)*$
以下是一些有趣的边缘案例:
- 的坟场
- 的Gravendeel
- 的坟场
- 的格雷文赞德
- 's Heer Arendskerke
- 的海伦伯格
- 的海伦胡克
- 海尔托亨博斯
- 不难
- 't Veld
- 赞德
- 100 英里的房子
- 10 月 6 日市
因此,不要忘记添加'
和0-9
作为城市名称的可能第一个字符。