Home > Net >  How would one make sure user input containing quotes works correctly with the in operator for conten
How would one make sure user input containing quotes works correctly with the in operator for conten

Time:01-14

I'm currently writing an app in python (tkinter) and have encountered an issue with user input strings. If they contain quotes (" or ') my code breaks down. My goal is to check wether the string contains any ASCII punctuation or digits (0123456789) and return and raise and error when it does.

Here is a minimal example:

import string
a = '1"#' 
# A specific troubled string, but usually a tkinter.StringVar 
# using the .get() method that returns a str. The StringVar is part of a ttk.Entry field 
# which is essentially equivalent with built-in input() for this purpose
# ( " is intentionally not an
# escaped character since this is how both input() and tkinter return the string)

if a in string.digits.join(string.punctuation):
    raise ValueError("incorrect")
else:
    pass
    # handle input

This expression evaluates to False with the above string a and any other string containing the charaters " or ' as far as I can tell. Same thing happens if I separate it as (a in string.digits) or (a in string.punctuation). Every other string i've tried works fine, just not these. I have also tried using the str.replace() method in python which would give this example:

import string

a = '1"#' 

if a.replace('\"', "").replace("\'", "") in string.digits.join(string.punctuation):
    raise ValueError("incorrect")
else:
    pass
    # handle input

But this also has the same issue. Is there any way to solve this?

P.S. here are the same examples with the actual StringVar with the placeholder string if that helps but it's much less minimal this way:

import string
import tkinter as tk

_ = tk.Tk() # This is neccesary to appease tkinter but not used

a = tk.StringVar(value='1"#')

if a.get() in string.digits.join(string.punctuation):
    raise ValueError("incorrect")
else:
    pass
    # handle input
import string
import tkinter as tk

_ = tk.Tk() # This is neccesary to appease tkinter but not used

a = tk.StringVar(value='1"#') 

if a.get().replace('\"', "").replace("\'", "") in string.digits.join(string.punctuation):
    raise ValueError("incorrect")
else:
    pass
    # handle input

CodePudding user response:

The quotes have nothing to do with it. That's not how you tell if a string contains punctuation or digits. string1 in string2 is true if string1 is a substring of string2.

I'm not sure why you're using .join(). That creates a string where each punctuation character is separated by all the digits:

'!0123456789"0123456789#0123456789$012345678923456789&0123456789\'0123456789(0123456789)0123456789*0123456789 0123456789,0123456789-0123456789.0123456789/0123456789:0123456789;0123456789<0123456789=0123456789>0123456789?0123456789@0123456789[0123456789\\0123456789]0123456789^0123456789_0123456789`0123456789{0123456789|0123456789}0123456789~'

Very few strings consisting only of digits and punctuation are substrings of that.

The way to do what you want is with the every() function to loop over all the characters in a, testing each of them to ensure it's either a digit or punctuation.

digits_and_punc = set(string.digits   string.punctuation)
if every(c in digits_and_punc for c in a):
    pass
else:
    raise ValueError("incorrect")
  • Related