Самый простой способ добиться этого - поместить метод input
в цикл while. Используйте continue
, когда вы получаете плохой ввод, и break
выходят из цикла, когда вы удовлетворены.
Попробуйте попытаться и поймать , чтобы определить, когда пользователь вводит данные, которые не могут быть проанализированы.
while True:
try:
# Note: Python 2.x users should use raw_input, the equivalent of 3.x's input
age = int(input("Please enter your age: "))
except ValueError:
print("Sorry, I didn't understand that.")
#better try again... Return to the start of the loop
continue
else:
#age was successfully parsed!
#we're ready to exit the loop.
break
if age >= 18:
print("You are able to vote in the United States!")
else:
print("You are not able to vote in the United States.")
Если вы хотите отклонить значения, которые Python может успешно проанализировать, вы можете добавить свою собственную логику проверки.
while True:
data = input("Please enter a loud message (must be all caps): ")
if not data.isupper():
print("Sorry, your response was not loud enough.")
continue
else:
#we're happy with the value given.
#we're ready to exit the loop.
break
while True:
data = input("Pick an answer from A to D:")
if data.lower() not in ('a', 'b', 'c', 'd'):
print("Not an appropriate choice.")
else:
break
Оба вышеуказанных метода могут быть объединены в один цикл.
while True:
try:
age = int(input("Please enter your age: "))
except ValueError:
print("Sorry, I didn't understand that.")
continue
if age < 0:
print("Sorry, your response must not be negative.")
continue
else:
#age was successfully parsed, and we're happy with its value.
#we're ready to exit the loop.
break
if age >= 18:
print("You are able to vote in the United States!")
else:
print("You are not able to vote in the United States.")
Если вам нужно спросить у вашего пользователя множество разных значений, может быть полезно поместить этот код в функция, поэтому вам не нужно повторно указывать ее каждый раз.
def get_non_negative_int(prompt):
while True:
try:
value = int(input(prompt))
except ValueError:
print("Sorry, I didn't understand that.")
continue
if value < 0:
print("Sorry, your response must not be negative.")
continue
else:
break
return value
age = get_non_negative_int("Please enter your age: ")
kids = get_non_negative_int("Please enter the number of children you have: ")
salary = get_non_negative_int("Please enter your yearly earnings, in dollars: ")
Вы можете расширить эту идею, чтобы создать очень общую функцию ввода:
def sanitised_input(prompt, type_=None, min_=None, max_=None, range_=None):
if min_ is not None and max_ is not None and max_ < min_:
raise ValueError("min_ must be less than or equal to max_.")
while True:
ui = input(prompt)
if type_ is not None:
try:
ui = type_(ui)
except ValueError:
print("Input type must be {0}.".format(type_.__name__))
continue
if max_ is not None and ui > max_:
print("Input must be less than or equal to {0}.".format(max_))
elif min_ is not None and ui < min_:
print("Input must be greater than or equal to {0}.".format(min_))
elif range_ is not None and ui not in range_:
if isinstance(range_, range):
template = "Input must be between {0.start} and {0.stop}."
print(template.format(range_))
else:
template = "Input must be {0}."
if len(range_) == 1:
print(template.format(*range_))
else:
print(template.format(" or ".join((", ".join(map(str,
range_[:-1])),
str(range_[-1])))))
else:
return ui
С использованием, например:
age = sanitised_input("Enter your age: ", int, 1, 101)
answer = sanitised_input("Enter your answer: ", str.lower, range_=('a', 'b', 'c', 'd'))
input
Заявления Этот метод работает, но обычно считается неудовлетворительным:
data = input("Please enter a loud message (must be all caps): ")
while not data.isupper():
print("Sorry, your response was not loud enough.")
data = input("Please enter a loud message (must be all caps): ")
Первоначально он может выглядеть привлекательно, потому что он короче, чем метод while True
, но он нарушает Не повторяйте сам принцип разработки программного обеспечения. Это увеличивает вероятность ошибок в вашей системе. Что делать, если вы хотите выполнить резервное копирование до 2.7, изменив input
на raw_input
, но случайно измените только первый input
выше?
Если вы только что узнали о рекурсии, возможно, у вас возникнет соблазн использовать ее в get_non_negative_int
, поэтому вы можете избавиться от цикла while.
def get_non_negative_int(prompt):
try:
value = int(input(prompt))
except ValueError:
print("Sorry, I didn't understand that.")
return get_non_negative_int(prompt)
if value < 0:
print("Sorry, your response must not be negative.")
return get_non_negative_int(prompt)
else:
return value
Кажется, что он работает отлично в большинстве случаев, но если пользователь вводит неверные данные достаточно времени, сценарий заканчивается с помощью RuntimeError: maximum recursion depth exceeded
. Вы можете подумать, что «ни один дурак не допустит 1000 ошибок подряд», но вы недооцениваете изобретательность дураков!
Если число всегда начинается с + и вы хотите получить полный номер без него, используйте:
\+(\d+(?:\s\d+)*)\b
и оно вернется (из вашего примера): 12 555 660 000
См. Онлайн: https://regex101.com/r/aEeIgK/2
Объяснение:
\+
начать с определения + перед началом нашего матча. Экранирование как + - это квантор регулярного выражения. \b
оканчиваются границей слова (поэтому, если смешанная строка начинается с цифр, она не будет частью совпадения). (\d+(?:\s\d+)*)
с круглыми скобками (...)
- это то, что будет совпадать. \d+
одна или несколько цифр в начале - это мачта. \d
является цифрой; +
квантификатор для одного или нескольких. (?:\s\d+)*
необязательные (ноль или более) строки, начинающиеся с пробела \s
, за которыми следуют цифры. (?:...)
- это несоответствие скобок. *
квантификатор для нуля или более. \s
пробел (только один).