Find a valid phone number using regular expression in python - 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

Related

How can I customise error messages shown by PyInputPlus?

How can I customise error messages shown by PyInputPlus in python?
I have tried many method but unable to do it.
import pyinputplus as pyip
number = pyip.inputNum("Enter your phone number : ",
min=1000000000,
max=9999999999)
number
I want to print error message as please enter a valid 10 digit phone number.
Is there any way to so it?
I try to use "allowRegexes and blockRegexes" but unable to understand it.
If you are using this for a real world project I would recommend using input from python itself, this lib doesn't seem very well documented and mantained. This could bring a lot of weird errors in your code for the future.
But to answer your question, you could do it using regex with the parameter blockRegexes. If you were unable to understand it, this will be more a regex question than a python question.
From this website you can learn a lot about regex, that I recommend, regex is a very important tool to understand.
About your problem, accordingly to the docs:
blocklistRegexes (Sequence, None): A sequence of regex str or
(regex_str, error_msg_str) tuples that, if matched, will
explicitly fail validation.
So, in your case the first item in the tuple, should be a regex to block everything that have more or less than 10 integers characters:
^\d{10}$
The full explanation for this regex can be found here
The second item in your touple should be the string you want to appear when the error occurs:
"please enter a valid 10 digit phone number"
So your code would be like this:
number = pyip.inputNum("Enter your phone number : ",
min=1000000000,
max=9999999999,
blockRegexes=[(r"^\d{10}$","please enter a valid 10 digit phone number")])

how to check last characters of a string

I'm trying to make a program that only accepts valid email addresses without using anything super fancy. I'm trying to use negative indexing to get the last characters of the string the user enters and make sure the input is valid. I can't seem to figure out how to check the last characters of the string using this method. Here's what I have so far:
email = 'None'
while email != '#gmail.com':
email = input("Please enter your email. It must be a valid Gmail email: ")
if '#gmail.com' in email[-11:0]:
continue
else:
print("Enter a valid Gmail email.")
I've tried rearranging the values in the index and changing the values themselves, but no matter what it always says to enter a valid email even if it does end in #gmail.com. I'm not trying to allow any valid email, I only care about Gmail emails so I need to work for this only.
str='abc#gmail.com'
sliced_str=str[-10:]
this gives a string with last 10 chars in string. But a better approach would be to use endswith() function like this:
if str.endswith("#gmail.com")
you also need to check if the user input has multiple #'s as well. SO, to consider both you can do something like this:
if str.count('#')==1 and str.endswith("#gmail.com")
To address the comments, you can create a simple function like this to check the mail address like this:
def check_mails(mail_address, dom_list):
for i in dom_list:
if mail_address.endswith(i):
return True
return False
and in your if condition :
if str.count('#')==1 and check_mails(str, ['#yahoo.com', '#gmail.com', '#hotmai.com'])
for checking if the user has intput only '#gmail.com' you can do that with the size of string like this: (considering an email has at least 3 characters before domain name)
if str.count('#')==1 and len(str)>=13 and str.endswith("#gmail.com")
You can use endswith:
if email.endswith("#gmail.com"):
If you want to stick with negative indexing, you need to get rid of the 0. Also, you only need the last 10 characters to match '#gmail.com'. This should work better: email[-10:].
In email[-11:0], the 0 after the colon makes it try to match all characters whose indices are greater than or equal to the length of the string minus 11, and also less than 0. There aren't any indices in that range, so it won't match anything.

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.

Searching for string and outputting the column

So, I'm trying to make someone input a string and make python search for the string in the first column, if found then output the entire row.
How'd I go about doing this? (using gspread)
If I understand your question correctly this is the code:
line = ("abcd")
try:
string = input("Please enter a string: ")
if string in line:
print(line)
else:
print("Your input is not in line.")
except ValueError:
print("An error has occured")
The in statement checks to see if the input is in the text and if it is then it prints it out. (You have to change line to match what you want and for multi-line use """ text """). The try and except statements make the program more robust - especially if you can only enter numbers (integers or floats). It won't crash thus is a good habit to get into. You can google the suffixes for except as there is quite a few.

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

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.

Categories