How can I check if the users input is a number? - python

I'm trying to create a function to check if the user inputs a number. If the user inputs a number my program should output an error message, if the users enters a string of letters, my program should proceed with program. How can I do this?
I've come up with this so far:
#Checks user input
def CheckInput():
while True:
try:
city=input("Enter name of city: ")
return city
except ValueError:
print ("letters only no numbers")
This function doesn't seem to work. Please help.

You are looking to filter out any responses that include digits in the string. The answers given will do that using a regular expression.
If that's all you want, job done. But you will also accept city names like Ad€×¢® or john#example.com.
Depending on how choosy you want to be, and whether you're just looking to fix this code snippet or to learn the technique that the answers gave you so that you can solve the next problem where you want to reject anything that is not a dollar amount, say),you could try writing a regular expression. This lets you define the characters that you want to match against. You could write a simple one to test if the input string contains a character that is not a letter [^a-zA-Z] (the ^ inside [ ] means any character that is not in the class listed). If that RE matches, you can then reject the string.
Then consider whether the strict rule of "letters only" is good enough? Have you replaced one flawed rule (no digits allowed) with another? What about 'L.A.' as a city name? Or 'Los Angeles'? Maybe you need to allow for spaces and periods. What about hyphens? Try [^a-zA-Z .-] which now includes a space, period and hyphen. The backslash tells the RE engine to treat that hyphen literally unlike the one in "a-z".
Details about writing a regex here:http://docs.python.org/3/howto/regex.html#regex-howto
Details about using the Re module in Python here: http://docs.python.org/3/library/re.html#module-re

import re
def CheckInput():
city = input('Enter name of city: ')
if re.search(r'\d', city):
raise Exception('Invalid input')
You wouldn't be type checking because in Python 3 all text inputs are strings. This checks for a decimal value in the input using regular expressions and raises an exception if one is found.

val = input("Enter name of city:")
try:
int( val )
except ValueError:
return val
else:
print("No numbers please")
Edit: I saw mention that no number should be present in the input at all. This version checks for numbers at any place in the input:
import re
val = input("Enter name of city:")
if re.search( r'\d', val ) is not None:
print("No numbers please")
else:
return val

You can use the type(variable_name) function to retrieve the type.

Related

Writing regular expression that have to meet certain requirements, regardless of specific symbols' order [duplicate]

This question already has answers here:
Regex for password must contain at least eight characters, at least one number and both lower and uppercase letters and special characters
(42 answers)
Closed 2 years ago.
I'm writing a program which returns a certain message depending on the strength of the inputted password. In order to be labelled as ''strong'', it has to meet certain requirements, which I'm going to list below in the program's documentation :
#! python3
# strongPassword.py
# Strong Password Detection
# Write a function that uses regular expressions to make sure
# the password string it is passed is strong. A strong password
# is defined as one that is at least eight characters long,
# contains both uppercase and lowercase characters, and has
# at least one digit. You may need to test the string against
# multiple regex patterns to validate its strength.
import pyperclip, re
passwordRegex = re.compile(r'''(
^(?=.*[A-Z].*[A-Z]) # at least two capital letters
(?=.*[!##$&*]) # at least one of these special characters
(?=.*[0-9].*[0-9]) # at least two numeric digits
(?=.*[a-z].*[a-z].*[a-z]) # at least three lower case letters
.{10,} # at least 10 total digits
$
)''', re.VERBOSE)
def userInputPasswordCheck():
ppass = input("Enter a potential password: ")
mo = passwordRegex.search(ppass)
if (not mo):
print("Not strong, bling blong")
return False
else:
print("Long, Strong, and down to get the crypto on")
return True
userInputPasswordCheck()
I found this code on Github, but I don't quite understand how it manages to create a regular expression that doesn't list certain parts of the pattern in order.
What my concrete question is, is how am I able to write a regex in a more ''vague'' manner ( only mentioning the requirements, like minimum x number of upper case characters, y number of lower case characters and z number of digits, without highlighting the order in which each part has to occur ).
This particular code seems to use ''?='', which I don't fully understand ( lookahead assertion, matching the particular part of the string only if it's followed by another specific part of the string, I know, I just don't understand how it's utilized in this particular code ).
I'd greatly appreciate any assistance.
Thanks in advance.
Here is how:
from re import search
def userInputPasswordCheck():
pas = input('Input your password: ')
if all([len(pas) > 7, search('[0-9]', pas), search('[a-z]', pas), search('[A-Z]',pas)]):
print("Long, Strong, and down to get the crypto on")
return True
else:
print("Not strong, bling blong")
return False
userInputPasswordCheck()
Output:
Input your password: Hello101
Long, Strong, and down to get the crypto on

Find a valid phone number using regular expression in python

phn1='412-1114-1234'
if re.search("\d{3}-\d{3}-\d{4}",phn1):
print('It is a phone number')
else:
print('It is not a phone number')
Output: It is not a phone number
But, when I pass the input:
phn1='4123-111-1234'
Output: It is a phone number
What is wrong in the code that I get a wrong output in the second phone number?
It matches 123-111-1234 (Everything except the first digit). Change your regex to: ^\d{3}-\d{3}-\d{4}$ to make sure it only matches the whole input (example).
It is the search method behaviour, try match instead. When you try to search, it finds a match from 123-111-1234 this part. For more information: search vs match

python regex limit parenthesis to one time

I have a problem in Python where program has to check whether or not user enters a phone number in valid format such as: (111)-111-1111
I got this program to work using Python regex re.findall function, however, later on I realized that program lets user to enter as many parentheses as he wants, for example: (((((111)-111-1111 and this would still go trough the program as a valid format.
Question. Is there a way to limit the number of parentheses to the way the format would be as (111)-111-1111?
My code is as follows:
import re
number=input("Please enter phone number: " )
x=re.findall('([(+*)]\d{3}[(+*)][a-]\d{3}[a-]\d{4})', number)
if (x):
print("Perfect! Your format is valid: --> " "'"+number+"'")
else:
print("Not a valid format, please enter as (###)-###-####")
You were really close to have your code working.
You will just need to adapt your sample into:
import re
number=input("Please enter phone number: " )
x=re.match('^([(+*)]\d{3}[(+*)][a-]\d{3}[a-]\d{4})$', number)
if (x):
print("Perfect! Your format is valid: --> " "'"+number+"'")
else:
print("Not a valid format, please enter as (###)-###-####")
Where, instead of using findall, you use match as you are checking that the number does respect the pattern (the regex) and as you are not looking to extract some sub information from it.
Also you will need to add anchors (^, $) in your regex to enforce that the input string does not contain other characters in the beginning or at the end.
Output:
Please enter phone number: '(111)-111-1111'
Perfect! Your format is valid: --> '(111)-111-1111'
Please enter phone number: '(((((111)-111-1111'
Not a valid format, please enter as (###)-###-#
For validating mobile numbers like (111)-111-1111 I don't think you need a overly complicated and incorrect regex like this ([(+*)]\d{3}[(+*)][a-]\d{3}[a-]\d{4}) Even if you put start anchor ^ and end anchor $ it is going to validate following mobile numbers as valid which would be in correct,
)111(a111a1111
*111+-111-1111
Check this demo to see how it allows invalid mobile numbers
For validating mobile number like this (111)-111-1111, you can just use following regex,
^\(\d{3}\)-\d{3}-\d{4}$
Demo for correctly validating mobile numbers
Let me know in case you want to allow any variations of this (111)-111-1111 mobile number as valid.
Also, for validating a text, you should use match function instead of findall where later is used to extract information from a text and former for matching a text for validity.
Here is a sample python code which shows how you should validate your mobile numbers,
import re
arr = ['(111)-111-1111','(((((111)-111-1111',')111(a111a1111','*111+-111-1111']
for s in arr:
if (re.match(r'^\(\d{3}\)-\d{3}-\d{4}$', s)):
print(s, ' --> is Valid mobile number')
else:
print(s, ' --> is Not Valid mobile number')
Prints,
(111)-111-1111 --> is Valid mobile number
(((((111)-111-1111 --> is Not Valid mobile number
)111(a111a1111 --> is Not Valid mobile number
*111+-111-1111 --> is Not Valid mobile number
You can use the line below:
x=re.findall('^\(\d{3}\)-\d{3}-\d{4}$', number)
This also checks for beginning and ending characters.

How can I validate user input with regex with option to enter multiple entries using comma's?

I'm trying to create a python script that prompts the user for the slot location of a hard drive in a server. I would like it to match the pattern n:n:n where 'n' is a single digit number. They should also have the option of entering multiple slots using commas.
So far I have the following but it only works with a single entry? I've commented out the '.split()' because I would get an error:
Traceback (most recent call last):
File "v2hdorders.py", line 22, in <module>
if not re.match("\d:\d:\d", c):
File "/usr/local/Cellar/python#2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 141, in match
return _compile(pattern, flags).match(string)
TypeError: expected string or buffer
The code:
import re
while True:
c = raw_input("What is the slot position of the hard drive(s)? (e.g. 0.0.0 - Use commas if more than one drive): ")#.split()
if not re.match("\d:\d:\d:", c):
print ("Please enter in n:n:n format")
else:
d = raw_input("What is the disk size (Specify in GB or TB)? ")
break
I would like the user to be able to enter one or more slot entries while having the program check that the format is n:n:n
There is some confusion between your text and regex. You should know that the 'dot' character is special in regex syntax. So if you want a.b.c, you have to use a backslash in your regex for the '.' character: r'a\.b\.c' or whatever. (Or go with colon, ':', which seems fine.)
You can get the result you want by matching a single match, followed by zero-or-more occurrences of comma+match. You should make a habit of using raw-strings (r'' or r"" or ...) to write regular expressions, because they let you avoid extra backslashes:
re.match(r'match(,match)*')
The pattern above will match "match" or "match,match" or match,match,match", etc.
So, since your desired match appears to be either \d\.\d\.\d or perhaps \d:\d:\d, we can insert that instead:
re.match(r'\d:\d:\d(,\d:\d:\d)*')
(Note: I have not allowed for spaces, which you should do.)
Once you check for a match, I'll suggest using re.findall to iterate through the possibilities. It solves the whole problem of "how do I know if there's one or more of these matches?" for you!
for slot_pos in re.findall(r'\d:\d:\d', c):
print("Slot pos:", slot_pos)
You could use re.search to find the pattern then use re.match to return a boolean informing you if it matched your pattern.
import re
while True:
c = input("What is the slot position of the hard drive(s)? (e.g. 0.0.0 - Use commas if more than one drive): ")#.split()
match = re.search(r"\d:\d:\d", c)
print(match)
if not match :
print ("Please enter in n:n:n format")
else:
d = input("What is the disk size (Specify in GB or TB)? ")
break
I won't go into the split with commas functionality, because I think you may want to reconsider how you're going about that. If you delimit with commas here, you'll need to make sure the storage capacities also maintain their relationship with the drive number.
Worth mentioning, you had an error in your regex as well. You were asking for \d:\d:\d: which would be something like 0:1:3: where you're working with Dell servers and you're not going to have that trailing colon, therefore I changed it to \d:\d:\d.

Using user input as regex search expression

I am working on a personal project that is designed to open a file specified by the user, then to take in user input and use that input as a regular expression to search the file with. The purpose of this is to gain a deeper understanding of how regular expressions work, and how to incorporate them into programs.
My problem lies in that all input the user gives me is formatted as a string. So (correct me if I'm wrong), an input of [a-z]+ will result in the search expression "[a-z]+". This is a problem if I want r"[a-z]+" as my search expression, as putting that in as user input will give me "r"[a-z]+"" (again, correct me if I'm wrong). This will obviously not work with regex. How do I format the input so that an input of r"[a-z]+" remains r"[a-z]+"?
This is the code section in question. The textFile in the function arguments is imported from another section of the program, and is used in the regex search:
def new_search_regex(textFile):
"""Query for input, then performs RegEx() with user's input"""
global totalSearches
global allSearchResults
# ask user for regular expression to be searched
expression = raw_input("Please enter the Regular Expression to be searched: ")
# perform initial regex search
foundRegex = re.search(expression, textFile)
# if Regex search successful
if foundRegex != None:
# Do complete regex search
foundRegex = re.findall(expression, textFile)
# Print result
print "Result: " + str(foundRegex)
# Increment global total
totalSearches += 1
# create object for result, store in global array
reg_object = Reg_Search(totalSearches, expression, foundRegex)
allSearchResults.append(reg_object)
print "You're search number for this search is " + str(totalSearches) # Inform user of storage location
# if Regex search unsuccessful
else:
print "Search did not have any results."
return
Note: At the end I create an object for the result, and store it in a global array.
This is also assuming for now that the user is competently entering non-system destroying regex's. I will soon start adding in error checking though, such as using .escape on the user input. How will this affect my situation? Will it wreak havoc with the user including " in the input?
The r"..." syntax is only useful to prevent the python compiler to interpret escape sequences (\n being converted to newline character for example). Once parsed by the compiler it will just be a regular string.
We you read input from the user with `raw_input the compiler does not perform any escape sequence interpretations. You don't have to do anything, the string is already correctly interpreted.
You can test this yourself like that:
>>> x = r"[a-z]+\n"
>>> y = raw_input("")
[a-z]+\n
>>> x == y
True
Directly coming from the Python http://docs.python.org/2/library/re.html:
import re
m = re.search(regexp_as_string, payload)
m.group(0) #first occurence of the pattern

Categories