如何让Python Discord Bot接收多词输入并搜索JSON数据匹配ID
我有如下JSON数据片段:
{"draw":0,"recordsTotal":1261,"recordsFiltered":1261,"data":[{"id":"1","ClassID":null,"Name":"Default Sword","Description":"Default weapon for Legends!","Type":"Sword","Element":"None","File":"items/swords/GasparianBlade.swf","Link":"GasparianBlade","Icon":"iwsword","Equipment":"Weapon","Level":"1","DPS":"25","Range":"10","Rarity":"3","Quantity":"1","Stack":"1","Cost":"0","Coins":"0","Crystal":"0","Sell":"1","Market":"1","Temporary":"0","Upgrade":"0","Founder":"0","Vip":"0","Staff":"0","EnhID":"1","FactionID":null,"ReqReputation":"0","ReqClassID":null,"ReqClassPoints":"0","ReqQuests":"","QuestStringIndex":"-1","QuestStringValue":"0","Meta":null,"Color":"ffffff"},{"id":"2","ClassID":"1","Name":"Vagabond","Description":"A Vagabond that doesn't have much of experience, we must keep moving and learn more about our Adventure!","Type":"Class","Element":"None","File":"CyberPeasant.swf","Link":"CyberPeasant","Icon":"cclass","Equipment":"ar","Level":"1","DPS":"25","Range":"50","Rarity":"3","Quantity":"1","Stack":"1","Cost":"0","Coins":"0","Crystal":"0","Sell":"1","Market":"1","Temporary":"0","Upgrade":"0","Founder":"0","Vip":"0","Staff":"0","EnhID":"1","FactionID":null,"ReqReputation":"0","ReqClassID":null,"ReqClassPoints":"0","ReqQuests":"","QuestStringIndex":"-1","QuestStringValue":"0","Meta":null,"Color":"ffffff"},{"id":"3","ClassID":null,"Name":"Balrog Blade (Beta)","Description":...
我开发了一个Python Discord Bot,预期用户输入“Default Sword”时返回对应ID:1,但Bot只识别第一个单词“Default”,提示“ID not found”。现有代码如下:
@bot.command() async def item(ctx, item): data = "* data *" info_dict = json.loads(data) # Taking user input user_input_name = item # Find and print the ID if Name matches for entry in info_dict['data']: if entry.get("Name") == user_input_name: await ctx.send(f"Name : {item} - ID : {entry['id']}") break else: await ctx.send("ID not found. try writing full name.")
请问如何修改脚本,让它能接收完整的多词输入并匹配JSON中的名称,返回对应ID?
问题根源是Discord.py默认的命令参数解析逻辑:位置参数只会捕获第一个空格前的内容。要支持多词输入,有两种实用方案:
方案1:用*接收所有剩余参数
将命令参数改为*item,此时item会被解析为包含所有输入单词的元组,再拼接成完整字符串即可:
@bot.command() async def item(ctx, *item): # 把元组拼接成完整名称 user_input_name = " ".join(item) data = "* data *" info_dict = json.loads(data) for entry in info_dict['data']: if entry.get("Name") == user_input_name: await ctx.send(f"Name : {user_input_name} - ID : {entry['id']}") break else: await ctx.send("ID not found. try writing full name.")
方案2:用str转换器强制接收字符串(需引号包裹输入)
通过str转换器明确指定参数为字符串类型,但用户需要用引号包裹多词内容(比如输入!item "Default Sword"):
@bot.command() async def item(ctx, item: str): user_input_name = item data = "* data *" info_dict = json.loads(data) for entry in info_dict['data']: if entry.get("Name") == user_input_name: await ctx.send(f"Name : {user_input_name} - ID : {entry['id']}") break else: await ctx.send("ID not found. try writing full name.")
优先推荐方案1,无需用户额外操作引号,使用体验更流畅。
内容的提问来源于stack exchange,提问作者Daemon

