正则表达式 PyTelegramBotApi float int 类型消息
Regex PyTelegramBotApi float int type messages
我正在使用 PyTelegramBotApi 库创建一个机器人。当我要求用户输入一个参数时,我的目标是如果他只发送一个int或float类型的消息就接受,否则要求他重新输入。当我使用下面的代码时,bot 接收并存储用户发送的 int 消息,但如果输入 float 类型的消息,则要求重新输入。
import re
import telebot
from telebot import types
bot = telebot.TeleBot(TOKEN)
pattern = r'\d{1,7}\.\d'
def perimeter(message):
global p, pattern
if re.match(message.text, pattern) or message.text.isdigit():
p = float(message.text)
print('p:', p, type(p))
bot.send_message(message.chat.id, "Message saved")
else:
msg = bot.send_message(message.chat.id, "Please try again!")
bot.register_next_step_handler(msg, perimeter)
bot.infinity_polling()
您的参数顺序错误,re.match()
需要模式在前,然后是文本。
re.match()
如果模式在字符串中的任何位置 将为真 如果字符串以模式开头。因此,根据您当前的逻辑,"ABC0.123XYZ"
"0.123XYZ"
会 return True 然后无法解析。
你不应该用 isdigit
做额外的检查,只要在你做正则表达式时在你的模式中包含那个案例(数字中的可选 .
)。
现在您将浮点数限制在 .
之后的一位数字,这真的是您想要的吗?拒绝任何有 2 位或更多小数位的内容?
编辑:
由于您并没有真正得到关于如何使其工作的答案 - 您可以在没有正则表达式的情况下轻松地做到这一点:
import re
import telebot
from telebot import types
bot = telebot.TeleBot(TOKEN)
def perimeter(message):
global p
try:
p = float(message.text)
print('p:', p, type(p))
bot.send_message(message.chat.id, "Message saved")
except ValueError:
msg = bot.send_message(message.chat.id, "Please try again!")
bot.register_next_step_handler(msg, perimeter)
bot.infinity_polling()
如果您想使用正则表达式:
import re
import telebot
from telebot import types
bot = telebot.TeleBot(TOKEN)
pattern = "\d+(\.\d+)?$"
def perimeter(message):
global p, pattern
if re.fullmatch(pattern, message.text):
p = float(message.text)
print('p:', p, type(p))
bot.send_message(message.chat.id, "Message saved")
else:
msg = bot.send_message(message.chat.id, "Please try again!")
bot.register_next_step_handler(msg, perimeter)
bot.infinity_polling()
此外,我认为没有必要将 p
和 pattern
声明为全局变量,因为这只会在您更改它们然后在方法之外再次使用它们时执行某些操作,并且想要更改后的值。即使这样做,最好使用 return 值。
既然您将接受 int 或 float,为什么不定义您的正则表达式来匹配 int 或 float,例如:
pattern = r'\d+(\.\d*)?$'
那么您可以直接使用re.match()
,而不必进行任何其他检查。要么匹配要么不匹配。
请务必如上所示以“$”结束您的模式,这样您就不会接受可能以有效的 int 或 float 开头,但之后有其他垃圾字符的字符串(如 12.34ZYX
).
您的代码中的其他一些位:
@ewz93 关于反转 re.match
的论点的评论是正确的。模式应该在第一位,被匹配的字符串在第二位。
global pattern, p
不是必需的,至少看一下您发布的代码。您在代码中 do 分配给 p
,因此您以后可能会在其他地方引用它(但通过全局变量执行此操作并不是最好的 Python 做法)。 pattern
仅在此代码中读取,因此您的函数可以访问 module-level pattern
而无需将其声明为全局。如果您的函数 为 module-level pattern
分配了一个值 , 那么 您将需要使用 global
.
刚刚将 p
创建为 p = float(message.text)
,关于 p
的类型应该没有任何问题,所以打印出 type(p)
将始终为“浮动”。 在使用 print()
进行调试时包含某种类型的输出很好,通常只需 print(repr(p))
就足够了 - repr()
输出通常包含一些类型的指示(字符串在引号中,浮点数用小数位格式化,列表显示在 [] 中,等等)。如果您使用的是 Python 3.6 或更高版本,您可以像这样使用 f-string 来执行此操作:print(f"{p!r}")
。尾随 !r
是您显示该值的 repr 的方式。
我正在使用 PyTelegramBotApi 库创建一个机器人。当我要求用户输入一个参数时,我的目标是如果他只发送一个int或float类型的消息就接受,否则要求他重新输入。当我使用下面的代码时,bot 接收并存储用户发送的 int 消息,但如果输入 float 类型的消息,则要求重新输入。
import re
import telebot
from telebot import types
bot = telebot.TeleBot(TOKEN)
pattern = r'\d{1,7}\.\d'
def perimeter(message):
global p, pattern
if re.match(message.text, pattern) or message.text.isdigit():
p = float(message.text)
print('p:', p, type(p))
bot.send_message(message.chat.id, "Message saved")
else:
msg = bot.send_message(message.chat.id, "Please try again!")
bot.register_next_step_handler(msg, perimeter)
bot.infinity_polling()
您的参数顺序错误,
re.match()
需要模式在前,然后是文本。re.match()
如果模式在字符串中的任何位置将为真如果字符串以模式开头。因此,根据您当前的逻辑,"ABC0.123XYZ"
"0.123XYZ"
会 return True 然后无法解析。你不应该用
isdigit
做额外的检查,只要在你做正则表达式时在你的模式中包含那个案例(数字中的可选.
)。现在您将浮点数限制在
.
之后的一位数字,这真的是您想要的吗?拒绝任何有 2 位或更多小数位的内容?
编辑:
由于您并没有真正得到关于如何使其工作的答案 - 您可以在没有正则表达式的情况下轻松地做到这一点:
import re
import telebot
from telebot import types
bot = telebot.TeleBot(TOKEN)
def perimeter(message):
global p
try:
p = float(message.text)
print('p:', p, type(p))
bot.send_message(message.chat.id, "Message saved")
except ValueError:
msg = bot.send_message(message.chat.id, "Please try again!")
bot.register_next_step_handler(msg, perimeter)
bot.infinity_polling()
如果您想使用正则表达式:
import re
import telebot
from telebot import types
bot = telebot.TeleBot(TOKEN)
pattern = "\d+(\.\d+)?$"
def perimeter(message):
global p, pattern
if re.fullmatch(pattern, message.text):
p = float(message.text)
print('p:', p, type(p))
bot.send_message(message.chat.id, "Message saved")
else:
msg = bot.send_message(message.chat.id, "Please try again!")
bot.register_next_step_handler(msg, perimeter)
bot.infinity_polling()
此外,我认为没有必要将 p
和 pattern
声明为全局变量,因为这只会在您更改它们然后在方法之外再次使用它们时执行某些操作,并且想要更改后的值。即使这样做,最好使用 return 值。
既然您将接受 int 或 float,为什么不定义您的正则表达式来匹配 int 或 float,例如:
pattern = r'\d+(\.\d*)?$'
那么您可以直接使用re.match()
,而不必进行任何其他检查。要么匹配要么不匹配。
请务必如上所示以“$”结束您的模式,这样您就不会接受可能以有效的 int 或 float 开头,但之后有其他垃圾字符的字符串(如 12.34ZYX
).
您的代码中的其他一些位:
@ewz93 关于反转
re.match
的论点的评论是正确的。模式应该在第一位,被匹配的字符串在第二位。global pattern, p
不是必需的,至少看一下您发布的代码。您在代码中 do 分配给p
,因此您以后可能会在其他地方引用它(但通过全局变量执行此操作并不是最好的 Python 做法)。pattern
仅在此代码中读取,因此您的函数可以访问 module-levelpattern
而无需将其声明为全局。如果您的函数 为 module-levelpattern
分配了一个值 , 那么 您将需要使用global
.刚刚将
p
创建为p = float(message.text)
,关于p
的类型应该没有任何问题,所以打印出type(p)
将始终为“浮动”。 在使用print()
进行调试时包含某种类型的输出很好,通常只需print(repr(p))
就足够了 -repr()
输出通常包含一些类型的指示(字符串在引号中,浮点数用小数位格式化,列表显示在 [] 中,等等)。如果您使用的是 Python 3.6 或更高版本,您可以像这样使用 f-string 来执行此操作:print(f"{p!r}")
。尾随!r
是您显示该值的 repr 的方式。