我试图使用pyinputplus
来验证存储航班安排的一些输入。特别是我有allowRegexes
关键字的问题。
>>> import pyinputplus as pyip
>>> confirmation_number = pyip.inputStr(
... prompt='Confirmation number = ',
... allowRegexes=[r'w{6}']
... ).upper()
Confirmation number = #$%}|+_
>>> name = pyip.inputStr(
... prompt='Reservation name = ',
... allowRegexes=[r'([A-Za-z]+s[A-Za-z]+)']
... ).title()
Reservation name = F1rstn@me La$tnam3
>>> confirmation_number
'#$%}|+_'
>>> name
'F1Rstn@Me La$Tnam3'
我本以为这两个输入都被阻塞了。显然,两者都允许任何输入。
文档只解释allowRegexes
将覆盖blockRegexes
,我在网上找到的任何例子都提供了正则表达式和电话号码的例子,但不是什么是/不是相应地阻止。
为什么在pyinputplus中的allowRegexes关键字允许ABC在pyip.inputNum(allowRegexes=[r'(C)+'])?
问题是您对allowRegexes
参数的理解并不完全准确。虽然它是部分相关的,但您的问题不是重复的为什么在pyinputplus中的allowRegexes关键字允许ABC在pyip.inputNum(allowRegexes=[r'(C)+'])?事实上,在你的两个函数调用中有两个不同的误解。
-
您似乎期望只有与
allowRegexes
中的正则表达式匹配的输入将通过验证。但实际上,行为是,在allowRegexes
中匹配正则表达式的输入将是有效的,除了之外,那些已经被所使用的相应函数发现有效的。在您的示例中,这是函数
pyinputplus.inputStr()
,它接受任何字符串作为输入。因此,您的第一个函数调用说">接受任何输入,并且另外接受任何包含任意六个连续单词字符序列的输入"。显然,第二部分是多余的,所以这就是为什么要观察所描述的行为。要解决这个问题,您有几个选项:
(a)使用
blockRegexes
和allowRegexes
的组合:正如你正确写的,
allowRegexes
将覆盖blockRegexes
。所以你可以利用这一点,首先使用正则表达式.*
阻止任何输入,然后只允许你想要的输入:>>> confirmation_number = pyip.inputStr( ... prompt='Confirmation number = ', ... blockRegexes=[r'.*'], ... allowRegexes=[r'w{6}'] ... ).upper() Confirmation number = #$%}|+_ This response is invalid.
(b)用
pyinputplus.inputRegex()
代替有一个函数可以直接执行您所期望的操作。它是
pyinputplus.inputRegex()
:提示用户输入与提供的regex字符串(或regex对象)和标志匹配的字符串。返回输入的字符串
>>> confirmation_number = pyip.inputRegex(r'w{6}', ... prompt='Confirmation number = ' ... ).upper() Confirmation number = #$%}|+_ '#$%}|+_' does not match the specified pattern. Confirmation number = 123.45 '123.45' does not match the specified pattern. Confirmation number = abcde 'abcde' does not match the specified pattern. Confirmation number = abCD_E >>>
这解决了你的第一个问题。
-
如果您在第二个示例中尝试上述相同的解决方案,该字符串仍将被接受。其原因是
allowRegexes
的行为实际上在第二方面与您所期望的不同:regex不需要匹配整个输入。相反,如果allowRegexes
中的regex集匹配输入的任何部分,则整个字符串将有效(如果在blockRegexes
中使用,则分别无效)。让我用你的例子
F1rstn@me La$tnam3
来解释:你使用的正则表达式是([A-Za-z]+s[A-Za-z]+)
。虽然它不匹配完整的字符串F1rstn@me La$tnam3
,但它部分匹配中间部分me La
。因此,整个输入被认为是有效的。这也导致上面的第一个例子接受任何和所有包含6个单词字符序列的字符串。要解决这个问题,请调整您的正则表达式,使它们只接受恰好是您想要允许的序列。在您的示例中,这很容易通过将正则表达式包装在
^
(断言行首位置)和$
(断言行尾位置)中来实现:>>> confirmation_number = pyip.inputRegex(r'^w{6}$', ... prompt='Confirmation number = ', ... ).upper() Confirmation number = #$%}|+_ '#$%}|+_' does not match the specified pattern. Confirmation number = 123.45 '123.45' does not match the specified pattern. Confirmation number = abcde 'abcde' does not match the specified pattern. Confirmation number = 1234567890 '1234567890' does not match the specified pattern. Confirmation number = abcdefghij 'abcdefghij' does not match the specified pattern. Confirmation number = a2cD_e >>>
见https://regex101.com/r/I5OU0L/1
>>> name = pyip.inputRegex(r'^([A-Za-z]+s[A-Za-z]+)$', ... prompt='Reservation name = ' ... ).title() Reservation name = F1Rstn@Me La$Tnam3 'F1Rstn@Me La$Tnam3' does not match the specified pattern. Reservation name = F1Rstn@Me Lastname 'F1Rstn@Me Lastname' does not match the specified pattern. Reservation name = Firstnaem La$Tnam3 'Firstnaem La$Tnam3' does not match the specified pattern. Reservation name = Firstname Lastname >>>
见https://regex101.com/r/hDh40k/1
这第二个问题实际上与你在问题中链接的问题中的问题相同,可能是重复的…