Estoy tratando de usar pyinputplus para validar algunas entradas para almacenar arreglos de vuelo. En particular, tengo problemas con la palabra clave allowRegexes.

Aquí está mi código (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'

Hubiera esperado que ambas entradas se hubieran bloqueado. Al parecer, ambos permitirán cualquier entrada.

Los documentos solo explican que allowRegexes anulará blockRegexes, y cualquier ejemplo en línea que haya encontrado proporciona ejemplos de expresiones regulares y números de teléfono, pero no lo que está / no está bloqueado en consecuencia.

Posible duplicado de ¿Por qué es la palabra clave allowRegexes? en pyinputplus permitiendo ABC en pyip.inputNum (allowRegexes = [r '(C) +'])?

2
chemicalwill 5 mar. 2021 a las 17:45

1 respuesta

La mejor respuesta

El problema es que su comprensión del parámetro allowRegexes no es del todo precisa. Aunque está parcialmente relacionado, su pregunta no es un duplicado de ¿Por qué la palabra clave allowRegexes en pyinputplus permite ABC en pyip.inputNum (allowRegexes = [r '(C) +'])?. De hecho, hay dos conceptos erróneos diferentes en sus dos llamadas de función.

  1. Parece esperar que solo las entradas que coincidan con la expresión regular en allowRegexes pasarán la validación. Pero, de hecho, el comportamiento es que las entradas para las que la expresión regular en allowRegexes coincide serán válidas además de aquellas que ya son consideradas válidas por el función que se utiliza.

    En su caso, esa es la función pyinputplus.inputStr(), que acepta cualquier cadena como entrada. Entonces, su primera llamada a la función dice " Acepte cualquier entrada y, además, cualquier entrada que contenga una secuencia de seis caracteres de palabra consecutivos '. Claramente, la segunda parte es redundante, por eso observa el comportamiento descrito .

    Para remediar esto, tiene varias opciones:

    (a) Utilice una combinación de blockRegexes y allowRegexes:

    Como escribió correctamente, allowRegexes anulará blockRegexes. Entonces puede usar eso para su ventaja bloqueando primero cualquier entrada usando la expresión regular .* y luego permitiendo solo la entrada que desea:

    confirmation_number = pyip.inputStr(
    ...             prompt='Confirmation number = ',
    ...             blockRegexes=[r'.*'],
    ...             allowRegexes=[r'\w{6}']
    ...            ).upper()
    Confirmation number = #$%}|+_
    This response is invalid.
    

    (b) Utilice pyinputplus.inputRegex() en su lugar

    Hay una función que hace directamente lo que esperabas. Es pyinputplus.inputRegex():

    Pida al usuario que ingrese una cadena que coincida con la cadena de expresiones regulares (o el objeto de expresiones regulares) y las banderas provistas. Devuelve la cadena ingresada

    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
    >>> 
    
    

    Esto soluciona su primer problema.

  2. Si intenta la misma solución descrita anteriormente para su segundo ejemplo, la cadena seguirá siendo aceptada. La razón de esto es que el comportamiento de allowRegexes es en realidad diferente de lo que esperaba en una segunda forma: la expresión regular no necesita coincidir con la entrada completa . En cambio, si la expresión regular establecida en allowRegexes coincide con cualquier parte de la entrada, la cadena completa será válida (respectivamente inválida, si se usa en blockRegexes).

    Déjame explicarte usando tu ejemplo F1rstn@me La$tnam3: La expresión regular que usaste es ([A-Za-z]+\s[A-Za-z]+). Si bien esto no coincide con la cadena completa F1rstn@me La$tnam3, parcialmente coincide con la parte del medio me La. Por lo tanto, la entrada completa se acepta como válida. Esto también lleva al primer ejemplo anterior que acepta todas y cada una de las cadenas que tienen una secuencia de caracteres de 6 palabras en algún lugar.

    Para remediar esto, ajuste sus expresiones regulares para que acepten solo exactamente la secuencia que desea permitir. En su caso, esto se logra fácilmente envolviendo las expresiones regulares en ^ (afirma la posición al comienzo de una línea) y $ (afirma la posición al final de una línea):

    >>> 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
    >>> 
    

    Consulte 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
     >>> 
    

    Consulte https://regex101.com/r/hDh40k/1.

    Este segundo problema es en realidad el mismo que el del problema que vinculó en su pregunta como posible duplicado ...

2
buddemat 5 mar. 2021 a las 20:10