I'm trying to match a message from a user input that follows a certain pattern. 1st pattern is a keyword 'data' followed by two digits, and the 2nd is the keyword 'status' followed by a word. I used if statements and it works only if there is a single pattern to be matched but not both as the second pattern would be skipped.
import re
message = input('Enter Your Message?\n')
trainee_data_pattern = re.compile(r"^(data)?\s?(\d\d)$")
data_match = trainee_data_pattern.search(message)
trainee_status_pattern = re.compile(r"^(status)?\s?(\w )$")
status_match = trainee_status_pattern.search(message)
try:
if data_match.group() == message:
matched_num = trainee_data_pattern.search(message).group(2)
list1 = [11,22,33]
if int(matched_num) in list1:
print(f"ID: {matched_num}")
else:
print('no data')
elif status_match.group() == message:
matched_status = trainee_status_pattern.search(message).group(2)
list2 = ['good','bad','refurbished']
if matched_status in list2:
print(f"the status is {matched_status}")
else:
print('no data')
except AttributeError:
res = trainee_data_pattern.search(message)
print('wrong pattern')
The desired functionality of the program is when a user inputs: data 22 -> ID: 22
status good -> the status is good
data 133 -> wrong pattern
CodePudding user response:
re.MatchObject.group() function in Python Regex raise AttributeError if a matching pattern is not found.
In your case if input is e.g. 'status good', the code is in the first if statement raising an error and code is executing except block. In that case code is never passing to your elif block
You can do something like this:
import re
message = input('Enter Your Message?\n')
trainee_data_pattern = re.compile(r"^(data)\s(\d )\s(\d )")
trainee_status_pattern = re.compile(r"^(status)\s(\w )")
match = trainee_data_pattern.search(message)
if match:
matched_num = trainee_data_pattern.search(message).group(2)
list1 = [11, 22, 33]
if int(matched_num) in list1:
print(f"ID: {matched_num}")
else:
print('no data')
else:
match = trainee_status_pattern.search( message)
if match:
matched_status = trainee_status_pattern.search(message).group(2)
list2 = ['good', 'bad', 'refurbished']
if matched_status in list2:
print(f"the status is {matched_status}")
else:
print('no data')
CodePudding user response:
I solved the problem by combining the patterns into a single regular expression and instead using match groups to create conditions.
import re
message = input('Enter Your Message?\n')
general_pattern = re.compile(r"^(status|data)\s?(\d{2}|\w )$")
data_match = general_pattern.search(message)
try:
if data_match.group(1) == 'data':
list1 = [11, 22, 33]
mapped_list = map(str, list1)
if data_match.group(2) in list(mapped_list):
print(f"ID: {data_match.group(2)}")
else:
print('no data')
elif data_match.group(1) == 'status':
list2 = ['good', 'bad', 'refurbished']
if data_match.group(2) in list2:
print(f"the status is {data_match.group(2)}")
else:
print('no data')
except AttributeError:
data_match = general_pattern.search(message)
print('wrong pattern')