用于验证city/state.zip的正则表达式

本文关键字:zip 正则表达式 state 验证 city 用于 | 更新日期: 2023-09-27 18:27:50

我有一个ASP.NET/C#应用程序,它有一个表单字段,询问用户的位置,我们将其获取并传递给Bing Maps以进行地理编码。出于某种原因,我的客户希望将输入限制为以下三种格式:

San Francisco, CA 91111
San Francisco, CA
91111

然而,我知道他们最终也会要求支持加拿大邮政编码。

当然,他们在项目启动前2小时要求这样做,所以我真的没有太多时间自己研究regex并弄清楚(我对regex很糟糕),所以我想我会在这里问。

有人能想出一个RegEx吗?我可以用它来验证它是否符合上述三种格式之一,并支持加拿大邮政编码(不必支持ZIP+4)。

用于验证city/state.zip的正则表达式

我试过了,它似乎适用于您指定的所有情况:

var pattern =
    @"
    (^['w's]+,'s'w{2}$)|                        # City, State
    (^['w's]+,'s'w{2}'s'd{5}$)|                 # City, State and US PostCode
    (^['w's]+,'s'w{2}'s('w'd'w's?'d'w'd)$)|     # City, State and Canada PostCode
    (^'d{5}$)|                                  # US PostCode
    (^'w'd'w's?'d'w'd$)                         # Canada PostCode";

使用此正则表达式时,请确保:

  • 指定RegexOptions.IgnorePatternWhitespace

  • 使用精简版(可读性较差):(^['w's]+,'s'w{2}$)|(^['w's]+,'s'w{2}'s'd{5}$)|(^['w's]+,'s'w{2}'s('w'd'w's?'d'w'd)$)|(^'d{5}$)|(^'w'd'w's?'d'w'd$)

要匹配加拿大或美国邮政编码,可以使用^'d{5}(-'d{4})?$)|(^[ABCEGHJKLMNPRSTVXY]{1}'d{1}[A-Z]{1} *'d{1}[A-Z]{1}'d{1}$。由于当存在邮政编码时,您并不真正需要城市和州,因此当regex匹配时,您可以忽略其余的输入。因此,将正则表达式放入捕获组中并提取它。例如:

Regex postalCodeRegex = new Regex("^.*('d{5}(-'d{4})?$)|(^[ABCEGHJKLMNPRSTVXY]{1}'d{1}[A-Z]{1} *'d{1}[A-Z]{1}'d{1}).*$"
             , RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant);
Match m = postalCodeRegex.match(userInput);
if(m.Success) 
{
    String postalCode = m.Groups[1].Value;
    // Set location based on postal code
}
else 
{
    // Set location based on city
}

假设C#使用PCRE:

至少匹配一个字母字符,并允许城市使用空格和破折号

[A-Za-z's'-]+

后面跟着一个逗号,一个两个字符的状态代码,

,'s?[A-Za-z]{2}

后面跟着一个空格和一个5位数字或一个6个字符的字母串。

's('d{5}|[A-Za-z0-9]{3}'s?[A-Za-z0-9]{3})

因此,对于第一个例子,将所有内容结合起来。对于第二个例子,将前两个组合起来。对于您的第三个示例,请删除最后一部分的前导's

编辑:发现加拿大邮政编码中有时有空格。添加以支持这一点。

不确定这是否是最好的正则表达式,但请尝试:

(['D]+)? (['D]+)?(['d]+)?

编辑:

(['D]+)? (['D]+)?(['d]+)?(['d'D]+){2}

我不确定您要求的确切规格,但您可以使用这样的表达式来匹配示例中的格式字符串:

var re = @"(?xi)^'s*
    (?:
       [a-z][^,]+ , 's+ [a-z]{2}   
       (?: 's+ 'd{5} )?            # optional postal code
    |
        'd{5}                      # postal code
    |
        [a-z]'d[a-z]'s*'d[a-z]'d   # canadian code
    )
    's*$";

好。我自己不是正则表达式专家,我倾向于将问题分解为更小的正则表达式,然后使用它们。

因此,城市和州将是:

([a-zA-Z ]+, [a-zA-z ]+)

美国邮政编码为

('d{5})

加拿大邮政编码为:

([a-zA-Z]'d[a-zA-Z] ?'d[a-zA-Z]'d)

所以邮政编码应该是:

(('d{5})|([a-zA-Z]'d[a-zA-Z] ?'d[a-zA-Z]'d))

把它们放在一起给了我们:

(([a-zA-Z ]+, [a-zA-z]+) (('d{5})|([a-zA-Z]'d[a-zA-Z] ?'d[a-zA-Z]'d))?|(('d{5})|([a-zA-Z]'d[a-zA-Z] ?'d[a-zA-Z]'d)))

(城市和州后面跟着一个可选的ZIP,或一个单独的ZIP)

我相信有更简单的方法来写这些信,但我正在等待一份工作完成,我想我会把我的两个便士放在里

希望这能帮助

这需要做很多工作,但这将验证城市状态zip和城市状态的大多数版本。我们在生产中使用它来进行数以百万计的地址验证,所以它非常可靠。

((?:'w|'s|'w'.)+),?'s(?i:AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VI|VA|WA|WV|WI|WY|Alabama|Alaska|Arizona|Arkansas|California|Colorado|Connecticut|Delaware|District of Columbia|Florida|Georgia|Hawaii|Idaho|Illinois|Indiana|Iowa|Kansas|Kentucky|Louisiana|Maine|Maryland|Massachusetts|Michigan|Minnesota|Mississippi|Missouri|Montana|Nebraska|Nevada|New Hampshire|New Jersey|New Mexico|New York|North Carolina|North Dakota|Ohio|Oklahoma|Oregon|Pennsylvania|Rhode Island|South Carolina|South Dakota|Tennessee|Texas|Utah|Vermont|Virginia|Washington|West Virginia|Wisconsin|Wyoming)(|.('d{5}(-'d{4}|'d{4}|$)))$