我正在用 Python 开发一个不和谐的机器人,它将在黑名单上查找特定的触发词并对其进行审查。我已经让它大部分工作了,但是已经被审查的文字给它带来了问题。
我的解决方案是搜索“||” (对于那些不熟悉的人来说,将文本放在 || 组之间会将其放在不和谐的剧透标签后面),然后仅当单词不在它们之间时才运行该函数。我遇到的问题实际上是找到“||”的位置。
这是我第一次真正尝试使用 Python,而且主要是通过谷歌搜索,如果这是显而易见的事情,很抱歉 ^^'
为了清晰起见进行编辑:理想的输入输出示例是
在:“天哪,我死了”
出:“天哪,我太死了||ead||”
目前正在运行
在:“||天啊我死了||”
理想出局:“||天啊我死了||
当前无法运行并返回错误
我的第一次尝试是使用
censor_pos = [m.span() for m in re.finditer('||', mge, flags=0)]
其中“mge”是消息。这返回了字符串中的每个位置(又名“死”将返回 (0,0)(1,1)(2,2)(3,3),(4,4)) 我意识到这是因为 |是一个特殊的角色。censor_pos = [m.span() for m in re.finditer(re.escape('||'), mge, flags=0)]
(添加 re.escape)返回
TypeError: expected string or bytes-like object, got 'NoneType'
有趣的是,我确实尝试将 censor_pos 打印到控制台以查看发生了什么,它似乎确实获得了正确的位置,之后发生了错误。
因为我知道这可能是代码中其他地方的问题,所以这是我运行它的完整函数:
def Censor_Trigger(mge, word): #function to censor trigger words given a message and a trigger word
censor_pos = [m.span() for m in re.finditer(re.escape('||'), mge, flags=0)] #finds all instances of "||" to know which parts of message are censored
trigger_pos = [m.span() for m in re.finditer(word, mge, flags=re.IGNORECASE)] #finds all instances of a trigger word, giving positions as tuples in an array
censored_msg = mge
print (censor_pos)
print (trigger_pos)
y = 0 #variable to account for position change when censoring multiple instances of the same word
for x in trigger_pos:
a = 0
is_censored = False
for z in censor_pos:
if 0<=a and (a+1)<(len(censor_pos)):
if censor_pos[a][1]<=x[0]<=censor_pos[a+1][0]:
is_censored = True
return
else:
is_censored = False
a=a+1
if is_censored == False:
censored_msg = censored_msg[:x[1]+(y*4)] + "||" + censored_msg[x[1]+(y*4):]
censored_msg = censored_msg[:(x[0]+1+(y*4))] + "||" + censored_msg[(x[0]+1+(y*4)):]
y=y+1
print(censored_msg)
else:
return
return censored_msg
并且在 for 循环中调用
trigger_words = ["dead", "trigger", "example", "another"] #list of triggers
for x in trigger_words: #runs the function to censor trigger words for all words in the trigger list
Mess = Censor_Trigger(Mess, x)
完整的错误是
[2023-09-03 19:26:01] [ERROR ] discord.client: Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python311\Lib\site-packages\discord\client.py", line 441, in _run_event
await coro(*args, **kwargs)
File "C:\Users\user\Desktop\Discord Bot Fun\Test Code.py", line 17, in on_message
Mess = Censor_Trigger(Mess, x)
^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\user\Desktop\Discord Bot Fun\Test Code.py", line 37, in Censor_Trigger
censor_pos = [m.span() for m in re.finditer(re.escape('||'), mge, flags=0)] #finds all instances of "||" to know which parts of message are censored
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\user\AppData\Local\Programs\Python\Python311\Lib\re\__init__.py", line 223, in finditer
return _compile(pattern, flags).finditer(string)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: expected string or bytes-like object, got 'NoneType'
您想要完成的事情只有通过来自您自己的机器人的消息才能实现。 如Message.edit文档中所述,机器人可以不能编辑其他用户的消息,并且会引发
Forbidden
异常。
按照您想要的模式进行替换的代码将如下所示:
@bot.listen()
async def on_message(message: discord.Message):
censor_words = ["dead", "trigger", "example", "another"]
matching_item = next((item for item in censor_words if item in message.content), None)
if matching_item:
ret_message = message.content.replace(matching_item, f"{matching_item[0]}||{matching_item[1:]}||")
await message.edit(content=ret_message)