Python Discord机器人投票命令:如何实现多词投票标题?
解决方案
问题根源
Discord.py 的命令参数默认按空格分割,你的 message 参数只会接收第一个空格前的内容,剩余内容会被依次分配给 q1、q2 等选项参数,导致多词标题被拆分。
方案一:使用引号包裹标题(最简修改)
无需改动代码,只需让用户输入命令时用双引号把多词标题括起来,Discord.py 会自动将引号内的内容作为单个参数传递给 message:
$poll "Who is better?" Spider-Man Iron-Man
这样标题就能正确识别为 Who is better?,选项也不会混乱。
方案二:自动解析无引号多词标题(更友好)
如果想让用户不用加引号就能输入多词标题,可以自己处理消息内容,不依赖命令的自动参数拆分。修改后的代码如下:
@bot.command() async def poll(ctx): # 提取命令后的所有内容,去掉前缀和命令名 content = ctx.message.content[len(ctx.prefix + "poll"):].strip() if not content: await ctx.send("请输入投票标题和选项,格式:$poll [标题] [选项1] [选项2] [可选选项3-5]") return # 按空格拆分所有内容为列表 parts = content.split() # 选项最少2个,最多5个,从后往前匹配选项数量 option_count = None for count in range(5, 1, -1): if len(parts) >= count + 1: # 标题至少1个词 + 对应数量的选项 option_count = count break if not option_count: await ctx.send("至少需要2个选项,格式:$poll [标题] [选项1] [选项2] [可选选项3-5]") return # 拆分标题和选项 title = ' '.join(parts[:-option_count]) options = parts[-option_count:] # 表情映射与描述内容构造 reaction_emojis = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣'] msg_str = '\n'.join([f"{reaction_emojis[idx]} {opt}" for idx, opt in enumerate(options)]) # 创建嵌入消息并发送 embed = discord.Embed(title=title, description=msg_str) sent_msg = await ctx.send(embed=embed) # 添加对应数量的表情 for idx in range(option_count): await sent_msg.add_reaction(reaction_emojis[idx])
说明
- 代码会自动把最后2-5个词识别为选项,前面的所有词合并为投票标题,用户直接输入
$poll Who is better? Spider-Man Iron-Man即可正确识别。 - 增加了输入格式校验,当用户输入不合法时会给出明确提示。
- 用循环替代重复的if判断,代码结构更简洁。
方案三:用分隔符区分标题和选项(更灵活)
如果担心选项和标题混淆(比如选项包含特殊字符),可以指定分隔符(比如 --)明确区分标题和选项,代码示例:
@bot.command() async def poll(ctx): content = ctx.message.content[len(ctx.prefix + "poll"):].strip() if '--' not in content: await ctx.send("请使用格式:$poll [标题] -- [选项1] [选项2] [可选选项3-5]") return # 按分隔符拆分标题和选项部分 title_part, options_part = content.split('--', 1) title = title_part.strip() options = [opt.strip() for opt in options_part.split() if opt.strip()] if len(options) < 2 or len(options) >5: await ctx.send("选项数量需要在2-5个之间") return reaction_emojis = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣'] msg_str = '\n'.join([f"{reaction_emojis[i]} {opt}" for i, opt in enumerate(options)]) embed = discord.Embed(title=title, description=msg_str) sent_msg = await ctx.send(embed=embed) for i in range(len(options)): await sent_msg.add_reaction(reaction_emojis[i])
使用示例
$poll Who is better? -- Spider-Man Iron-Man
这种方式完全避免了标题和选项的歧义,适合选项可能包含特殊字符的场景。
内容的提问来源于stack exchange,提问作者Jynxie
相关产品推荐
相关产品推荐

