【问题标题】:Primitive Python IRC Chat bot for twitch用于抽搐的原始 Python IRC 聊天机器人
【发布时间】:2016-07-21 13:49:31
【问题描述】:

我目前正在为 Twitch.tv 开发 IRC 机器人,我想知道如何实现禁用词列表?这是我到目前为止所拥有的,由于我对 python 的了解有限,我感到很困惑。到目前为止,一切都运行良好,除了检查消息中是否包含禁用词。这是有问题的代码:

if bannedWords.split in message:
                sendMessage(s, "/ban " + user)
                break

我想检查一个列表,看看邮件是否包含列表中的任何内容?

bannedWords = ["badword1", "badword1"]

但我只是不确定..

import string
from Read import getUser, getMessage
from Socket import openSocket, sendMessage
from Initialize import joinRoom

s = openSocket()
joinRoom(s)
readbuffer = ""
bannedWords = ["badword1", "badword1"]
while True:
        readbuffer = readbuffer + s.recv(1024)
        temp = string.split(readbuffer, "\n")
        readbuffer = temp.pop()

        for line in temp:
            print(line)
            if "PING" in line:
                s.send(line.replace("PING", "PONG"))
                break
            user = getUser(line)
            message = getMessage(line)
            print user + " typed :" + message
            if bannedWords.split in message:
                sendMessage(s, "/ban " + user)
                break

提前致谢!!

【问题讨论】:

  • bannedWords 是你定义的禁用词列表吗?
  • 只是我添加的单词。一开始我有点想慢慢来。最后,也许我可以添加一个命令将单词写入 .txt 然后读取它们?
  • 您也忘记调用 split,您是在询问消息中是否包含对 str.split 的引用
  • temp.pop() 看起来也可能是一个问题区域......
  • 必填链接:Scunthorpe Problem。仔细考虑您希望过滤系统有多严格,因为您最终可能会压制合法对话。

标签: python bots irc twitch


【解决方案1】:

假设messagebannedWords 都是字符串:

if any(map(message.__contains__, bannedWords.split())):
    ...

另一方面,如果bannedWords 已经是一个列表,如您的代码示例,请跳过拆分(实际上list 类型没有方法split):

if any(map(message.__contains__, bannedWords)):
    ...

这将检查字符串的任何部分是否存在任何被禁止的单词; "The grass is greener on the other side." 将匹配 "ass" 等禁用词。

请注意,map 在两个主要 python 版本之间的行为不同:

  • 在 Python 2 中,map 创建了一个list,这否定了any 的短路行为所提供的优势。请改用生成器表达式:any(word in message for word in bannedWords)
  • 在 Python 3 中,map 创建了一个迭代器,该迭代器将延迟地将函数应用于给定的可迭代对象。

附言

关于bannedWords.split(),通常会看到在python中使用多行字符串文字生成的单词列表等:

bannedWords = """
banned
words
are
bad
mmkay
""".split()

【讨论】:

  • 我实际上也试过这个,但是由于某种原因,一旦在聊天中输入了一个被禁止的词,机器人就会崩溃。也许我的实现是错误的?
  • @Xarotic 您的问题并没有明确表明这就是您所追求的。添加您获得的回溯并改写您的问题。
  • 另外,您的意思是您之前尝试过这种类型的解决方案,还是您现在尝试了此答案的解决方案并从其他地方获得了新的异常?
  • @Ilja map 的使用在 2.x 和 3.x 中会有所不同(更不用说不必要地调用 dunder 方法只是看起来很痛苦) - 你可以使它保持一致并且同样清晰通过使用:if any(word in message for word in bannedWords)
  • @Ilja in 2.x map 将首先实现一个列表,这会破坏具有any 快捷方式行为的优势......(当然最终结果是相同的,并且只是一个简短的bannedWords 列表,没关系,但如果你将其扩展到大量,你正在构建一个不需要的列表)
【解决方案2】:

如果您想要完全匹配,请使用一组单词,在字符串上调用 lower 并检查这组坏单词是否不相交:

banned_set = {"badword1", "badword2"}
if banned_set.isdisjoint(message.lower().split())
   # no bad words

如果"foo" 被禁止并且"foobar" 完全有效,那么使用in/__contains__ 将错误地过滤单词,因此您需要仔细决定要走的路。

如果 banned_set.isdisjoint(message.lower().split()) 评估为 True,则继续进行是安全的:

In [3]: banned_set = {"badword1", "badword2"}

In [4]: banned_set.isdisjoint("foo bar".split())
Out[4]: True

In [5]: banned_set.isdisjoint("foo bar badword1".split())
Out[5]: False

【讨论】:

  • "foo""foobar" 的好点,完全错过了。
  • @Padraic Cunningham 谢谢,这对我来说更有意义!
  • 我在使用这个解决方案时遇到的问题是它试图禁止任何人说除了banned_set 中的单词之外的任何内容
  • 您的旧代码以另一种方式进行了测试。在您测试消息是否确实包含坏词的地方,此解决方案会测试是否有坏词。
  • 我刚刚意识到我的逻辑错误!,这是一个不好的方法吗? if banned_set.isdisjoint(message.lower().split()):breakelse: sendMessage(s, "/ban " + user)
猜你喜欢
  • 2018-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-29
  • 2023-01-23
  • 1970-01-01
相关资源
最近更新 更多