【问题标题】:discord.py: I want to grab a specific set of numbers from a message, but i'm stuckdiscord.py:我想从消息中获取一组特定的数字,但我被卡住了
【发布时间】:2019-08-28 07:11:18
【问题描述】:

我正在制作一个将用户链接到SCP Wiki (The foundation one) 的机器人。我希望我的机器人能够获取 SCP 分类(即 SCP-370)并返回一条消息,其中包含指向 scp wiki 的链接以及该编号(即http://scp-wiki.net/scp-370

我尝试了一些方法,例如:

def scp_url(num):
    return "http://www.scp-wiki.net/scp-" + num

def scp_link(num):
    return "[SCP-" + num + "](" + scp_url(num) + ")"

@client.event
async def on_message(message):
    if "SCP" in message.content:    
        msg = scp_link
        await client.send_message(message.channel, msg)

或者:

if int in message.content:
    int = num

我只是找不到从消息中获取数字的方法。

感谢任何帮助。

【问题讨论】:

  • 听起来我们需要编写一个具有明确定义的输入和输出的函数。您能否定义这些输入和输出,或者在表格中定义一些示例?

标签: python discord.py


【解决方案1】:

为此,您需要知道输入的格式。 从您的问题中,我看到它不是命令,因为它会检查每条消息中的 SCP 字符串。但是字符串会被格式化为SCP-1SCP-001SCP 1吗?

您需要处理所有这些情况,或者只选择 1 个选定的情况并进行处理。这是我处理所有 3 种情况的完整注释代码:

# Number separator is character between SCP and a number, example with space:
# SCP 1
NUMBER_SEPARATOR = " "
MAXIMUM_SCP_NUMBER = 4999


def get_scp_link(message_content):
    word_list = message_content.split(NUMBER_SEPARATOR)
    scp_number = _extract_scp_number(word_list)
    if scp_number is not None:
        try:
            # int(scp_number) takes care if users already entered 001
            # because it makes it equal to 1
            formatted_number = _format_scp_number(int(scp_number))
            return _build_scp_url(formatted_number)
        except Exception:
            return None


# @param word_list a list of strings
# @return integer or None if error
def _extract_scp_number(word_list):
    captured_scp_number = None

    for index, word in enumerate(word_list):
        if word == "SCP":
            # We're gonna return the word after the current word (index+1)
            # But we have to make sure that the next word exists in the list
            # otherwise we will get IndexError exception
            if index + 1 < len(word_list):
                captured_scp_number = word_list[index + 1]
            else:
                return None
    # If we captured a string in the for loop we have to make sure that that
    # string is actually a number and not some random word example "SCP blabla"
    if captured_scp_number is not None and captured_scp_number.isdigit():
        return captured_scp_number
    return None


# Formats number as a string in format 001-MAXIMUM_SCP_NUMBER
# This allows users to enter 1 instead of 001.
#
# @param number a positive integer to be formatted
# @return string in format 001-MAXIMUM_SCP_NUMBER or raise Exception if error
def _format_scp_number(number):
    if number == 0:
        raise Exception("SCP 0 doesn't exist!")
    elif number > MAXIMUM_SCP_NUMBER:
        raise Exception("SCP number too high! Entry doesn't exist!")
    elif number < 10:
        return "00" + str(number)
    elif number < 100:
        return "0" + str(number)
    else:
        return str(number)


# @param formatted_scp_number a string in format 001-MAXIMUM_SCP_NUMBER
# @return string representing URL to SCP-number web page
def _build_scp_url(formatted_scp_number):
    base_url = "http://www.scp-wiki.net/scp-"
    prefix = "[SCP-" + formatted_scp_number + "]"
    return prefix + base_url + formatted_scp_number

@client.event
async def on_message(message):
    if "SCP" in message.content:
        scp_link = get_scp_link(message.content)
        if scp_link is not None:
            await client.send_message(message.channel, scp_link)

如有任何问题或建议,请在下方评论。

【讨论】:

  • 如果它们都是函数,我应该把它们放在代码的什么地方?此外,对于最后一个函数,在最后一行,我收到一条错误消息,提示“等待在异步函数之外。除此之外,感谢您的时间和精力。
  • 对不起,我在本地测试时删除了它,忘记放回去了。我已经编辑它现在应该可以工作了。由于这些是您可以将它们放在任何地方的函数,因此您可以直接复制粘贴代码并将其粘贴到您已经拥有 on_message 函数的脚本中
  • 这很棒。每当我使用它时,我都会收到“AttributeError:'NoneType'对象没有属性'isdigit'”错误,但它仍然有效,所以我不介意。再次感谢您花费时间和精力编写此代码!
猜你喜欢
  • 2016-04-28
  • 1970-01-01
  • 2022-11-14
  • 1970-01-01
  • 1970-01-01
  • 2021-09-20
  • 2021-12-15
  • 1970-01-01
  • 2023-02-09
相关资源
最近更新 更多