Can';我不知道如何使用表达式在Python中验证加拿大邮政编码

Can';我不知道如何使用表达式在Python中验证加拿大邮政编码,python,expression,Python,Expression,我正在尝试制作一个程序,从用户那里获取邮政编码输入,并检查它是否有效。到目前为止,我已经: postalCode = input("Postal code: ") postalCode = postalCode.replace(" ", "") postalCode = postalCode.lower() letters = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "

我正在尝试制作一个程序,从用户那里获取邮政编码输入,并检查它是否有效。到目前为止,我已经:

postalCode = input("Postal code: ")

postalCode = postalCode.replace(" ", "")

postalCode = postalCode.lower()

letters = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
numbers = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

valid = True

for i in range(0, len(postalCode), 2):
  if postalCode[i] not in letters or postalCode[i+1] not in numbers:
  valid = False
  break

if(valid):
  print("Valid postal code.")
else:
  print("Not a valid postal code.")
代码运行得很好,但我知道使用表达式更可行,但我还没有弄清楚它们是如何工作的

加拿大邮政编码格式为:L/N/L N/L/N


谢谢,没有正则表达式解决方案:

直截了当地说出事实-a-z是错误的,由于相似性,某些字母被省略:

A Neufundland               B Nova Scotia           C Prince Edward Island
E New Brunswick             G Québec-Ost            H Montréal und Laval
J Québec-West               K Ontario-Ost           L Ontario-Mitte
M Groß-Toronto              N Ontario-Südwest       P Ontario-Nord
R Manitoba                  S Saskatchewan          T Alberta
V British Columbia          X NW-Territ. Nunavut    Y Yukon
代码:

输出:

A9A 9A9  =>  (True, 'A9A 9A9')
a9a 9a9  =>  (True, 'A9A 9A9')
A9A9A9  =>  (True, 'A9A 9A9')
a9a9a9  =>  (True, 'A9A 9A9')
w9A 9A9  =>  (False, 'Cant start with W or Z')
z9a 9a9  =>  (False, 'Cant start with W or Z')
a9a 9!9  =>  (False, "Illegal characters detected: ['!']")
Postal code: b2c3d4
(False, "Illegal characters detected: ['d']")
Press any key to continue . . .
此(不接受)提供正确的正则表达式

可能的邮政编码数()

邮政编码不包括字母D、F、I、O、Q或U,并且第一个位置也不使用字母W或Z。
[…]
,因为加拿大邮政为特殊功能保留了一些FSA,例如用于测试或促销目的(例如圣诞老人的h0h0,见下文)以及分拣前往加拿大境外目的地的邮件<代码>[…]

这就给你留下了没有WZ作为第一个字符的ABCEGHJKLMPRSTvxy


编辑:未执行的变更建议

  • 允许缺少的空间
  • 当大写/小写字母可以时,请更清楚

根据您的问题,您可以使用:

import re

postalCode = input("Postal code: ")


pattern = re.match(r'[A-Z]{1}[0-9]{1}[A-Z]{1}\s[0-9]{1}[A-Z]{1}[0-9]{1}',postalCode)
如果模式:

print('Valid postal code')
其他:


您也可以使用sub方法获取序列,这样就不必像我上面所做的那样重复代码。

我首先构造了两个字符串,其中一个字符串包含可以在邮政编码的任何(合法)位置使用的字母字符,和一个字符串,其中包含必须用于第一个位置的字母字符

>>> any_position = 'ABCEGHJKLMNPRSTVWXYZ'
>>> first_position = 'ABCEGHJKLMNPRSTVXY'
这几行代码显示了正则表达式及其在几个试用示例中的性能。如果
>>重新导入
>>>邮政编码=重新编译(r'^[ABCEGHJKLMPRSTVXY][0-9][ABCEGHJKLMPRSTVWXYZ][0-9][ABCEGHJKLMPRSTVWXYZ][0-9]$)
>>>邮政编码匹配('h0h0h0')
>>>邮政编码匹配('A0A 0A0')
>>>邮政编码匹配('W0A 0A0')
>>>邮政编码匹配('Q0A 0A0')
>>>邮政编码匹配('h0h0q0')

值得一提的是,这种方法只测试代码的格式。测试它的有效性是不够的,因为很多很多代码都没有被使用。对于小容量测试,您可以使用web scraping技术中的一种工具来检查代码是否在实际使用中,甚至检查其格式是否有效。

我想您是说使用正则表达式
import re len(re.findall(pattern,string_to_search))
创建邮政编码的模式,然后查看
len
大于1是否有效。不是或的副本。第二个是javascript,使用禁止字符,第一个不是公认的答案(而是有效的正则表达式解决方案),非常好+1.备注2:不明显您是否接受小写,我认为允许ADADAD也不错,没有空格。在这两种情况下,它们都必须在某个时候转换回ADA DAD,但不基于大写或缺少但完全可推断的空格来拒绝用户输入是合理的。@JLPeyret感谢您的建议,修改了代码以使用上/下和缺少空格的默认值。两者在结果中都是固定的。您是加拿大公民,因此您的愿望是我的命令;)根据问题中提供的信息,正则表达式是正确的-不幸的是,并非所有A-Z都允许您使用错误的正则表达式进行验证-您的正则表达式不区分大小写,问题中的代码不区分大小写regex解决方案的短处使我的看起来有点长:)+1-但至少我会输出一些错误提示。问题使用了不区分大小写-您可以为that@PatrickArtner当前位置现在我回头看这个问题,我认为我的答案的主要缺陷是我没有解释这个正则表达式是如何工作的,这也是OP不确定的。正如在这里经常发生的那样,谁知道SO打算用我们可能提供的任何结果做什么?
print('Invalid postal code')
>>> any_position = 'ABCEGHJKLMNPRSTVWXYZ'
>>> first_position = 'ABCEGHJKLMNPRSTVXY'
>>> import re
>>> postal_code_re = re.compile(r'^[ABCEGHJKLMNPRSTVXY][0-9][ABCEGHJKLMNPRSTVWXYZ] [0-9][ABCEGHJKLMNPRSTVWXYZ][0-9]$')
>>> postal_code_re.match('H0H 0H0')
<_sre.SRE_Match object; span=(0, 7), match='H0H 0H0'>
>>> postal_code_re.match('A0A 0A0')
<_sre.SRE_Match object; span=(0, 7), match='A0A 0A0'>
>>> postal_code_re.match('W0A 0A0')
>>> postal_code_re.match('Q0A 0A0')
>>> postal_code_re.match('H0H 0Q0')