我正在为我的discord服务器编写机器人,我想充当亵渎过滤器。我从文本文件中读取了一个坏词列表,并将它们存储在一个数组中。每当用户发送消息时(在机器人正在监听的频道中),机器人然后检查该消息是否包括这些坏词中的一个或多个。为此,我使用以下代码:
badWords.each { |badword|
if content.downcase.include? badword
...
end
}
我的问题是,只有当消息内容中的坏词与数组中的最后一个字匹配时,if语句才会返回true
。如果它匹配数组的任何其他元素,则返回false
。
我是否误解了Array#each
的任何功能?
答案 0 :(得分:2)
尝试strip
一个坏词,因为它最终可以有\n
个签名。
if content.downcase.include?(badword.strip)
答案 1 :(得分:1)
我会将您的代码分解为更小的部分,以便您可以更好地了解正在发生的事情,然后使用Ruby的Enumerable methods之一来帮助使事情更简洁。另外,让我们使用Ruby_case的Ruby约定(bad_words
而不是badWords
)。
首先,让我们确保您的bad_words
数组不包含任何不需要的字符。最好一次修改bad_words
集合,而不是每次都修改每个元素。
虽然我们正在使用它,但由于我们的集合不会包含重复项,并且由于我们将多次搜索匹配元素,因此我们可以通过将数组转换为集合来大大提高效率:
require 'set'
bad_words = bad_words.map(&:strip).to_set
接下来让我们编写一个方法来检查内容是否包含坏词。我们将在方法名称的末尾加上一个问号,表示它返回一个布尔值:
def profane?(content)
bad_words.any? { |bad_word| content.include?(bad_word) }
end
如果传入下一个块的任何项返回#any?
,则true
方法返回true。
现在,您的操作代码可以致电profane?
并采取相应措施:
def filter_bad_words(content)
if profane?(content)
bot.send_message(event.channel.id, "Sorry #{event.user.name}, this message made my profanity senses tingle!")
bot.send_message(344559522003812354, "PROFANITY WARNING!!\n user: #{event.user.name}\n message: #{event.content}\n Please check if it is a cause for a warning. Use !?warn to give the user a warning.")
event.message.delete
true
end
end
如果内容是亵渎的话,我已经让方法返回true
,如果内容不是亵渎的话,我会默认返回nil
。如果您愿意,可以使用不同的返回值,并且可以根据该响应采取进一步的操作。