pyinputplus allowRegexes关键字允许任何输入



我试图使用pyinputplus来验证存储航班安排的一些输入。特别是我有allowRegexes关键字的问题。

下面是我的代码(python 3.8.5):
>>> 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)+'])?事实上,在你的两个函数调用中有两个不同的误解。

  1. 您似乎期望只有与allowRegexes中的正则表达式匹配的输入将通过验证。但实际上,行为是,在allowRegexes中匹配正则表达式的输入将是有效的,除了之外,那些已经被所使用的相应函数发现有效的

    在您的示例中,这是函数pyinputplus.inputStr(),它接受任何字符串作为输入。因此,您的第一个函数调用说">接受任何输入,并且另外接受任何包含任意六个连续单词字符序列的输入"。显然,第二部分是多余的,所以这就是为什么要观察所描述的行为。

    要解决这个问题,您有几个选项:

    (a)使用blockRegexesallowRegexes的组合:

    正如你正确写的,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
    >>> 
    

    这解决了你的第一个问题。

  2. 如果您在第二个示例中尝试上述相同的解决方案,该字符串仍将被接受。其原因是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

    这第二个问题实际上与你在问题中链接的问题中的问题相同,可能是重复的…

相关内容

  • 没有找到相关文章

最新更新