java - 有没有办法在不和谐消息中找到单词的确切字符串?
问题描述
目前我正在开发一个不和谐的机器人,它正在过滤消息。我的问题是在尝试过滤包含在其他单词中的单词时出现的,从而触发重复消息。
这是我的 filter.txt:
sad
sadness
sadnesses
因为“悲伤”也可以在“悲伤”中找到“悲伤”,所以每当写“悲伤”时,我都会误认为“悲伤”。
是否可以仅检测消息中的确切字符串?喜欢:I want to be happy, because sadness is bad
→“只检测悲伤”
我希望你明白我的意思。
代码:
public void onGuildMessageReceived(GuildMessageReceivedEvent e) {
File file = new File("src/filter.txt");
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
if(!line.startsWith("#")) {
if(e.getMessage().getContentRaw().contains(line)) {
User user = e.getJDA().getUserById(e.getAuthor().getIdLong());
e.getMessage().delete().queue();
user.openPrivateChannel().queue(privateChannel -> {
privateChannel.sendMessage("Bitte achte auf deine Sprache!").queue();
});
}
}
}
} catch (IOException e1) {}
}
解决方案
正如红衣主教 - 恢复莫妮卡和哈迪斯已经说过的那样,你应该看看正则表达式。
“Regex”代表“正则表达式”,描述了字符串的搜索模式。
使用 regex 可以做很多事情,所以如果您想了解更多信息,请查看教程。
(这是我在谷歌搜索时发现的第一个,当然你可以使用任何你喜欢的教程。)
对于您的用例,我建议以下内容:
首先,不要使用String.contains()
,因为它只适用于字符串,而不适用于正则表达式。
改用String.matches()
以下正则表达式:
"(?is).*\\bSTRING\\b.*"
因为做了一些转义,这就是没有它的正则表达式的样子:
(?is).*\bSTRING\b.*
我将解释它是如何工作的。
\b
\b
匹配单词边界。单词字符是a
- z
、A
- Z
、0
-9
和_
。这些字符的任何组合都被视为一个单词。
这样做的好处是,您可以在以下情况下匹配单词sad :
- “我很伤心。” →
.
句末的 不影响检测。 - “悲伤是我的事”→即使是第一个单词,它也匹配。(这也受 影响
.*
。)
当使用sad时,它不会匹配sad,因为这个词在后面继续:
- “我感到悲伤!” → 因为这个词没有在“sad”之后结束,所以不匹配。匹配“悲伤”会起作用。
. *
.
匹配除某些换行符以外的任何字符。((?s)
帮助我在这里。)
*
基本上说,它前面的部分出现零次或多次。
通过.*
在字符串之前和之后使用,正则表达式适用于字符串周围的任何字符或字符组合(包括无字符)。
这很重要,因为通过这种方式,单词可以放置在每个可以想象的句子中,并且无论如何都会匹配。
(?是)
?i
并?s
启用某些模式。
?i
使正则表达式不区分大小写。这意味着,无论是悲伤、悲伤还是悲伤;这三个都将匹配。
?s
启用“单行模式”,这意味着.
也匹配所有换行符。
?i
并且?s
可以组合到(?is)
然后放在正则表达式的前面。
而不是STRING
你只需要像这样插入你的话:
"(?is).*\\b" + line + "\\b.*"
您的代码最终将如下所示:
public void onGuildMessageReceived(GuildMessageReceivedEvent e) {
File file = new File("src/filter.txt");
try {
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
while ((line = br.readLine()) != null) {
if(!line.startsWith("#")) {
if(e.getMessage().getContentRaw().matches("(?is).*\\b" + line + "\\b.*")) {
User user = e.getJDA().getUserById(e.getAuthor().getIdLong());
e.getMessage().delete().queue();
user.openPrivateChannel().queue(privateChannel -> {
privateChannel.sendMessage("Bitte achte auf deine Sprache!").queue();
});
}
}
}
} catch (IOException e1) {}
}
如果您希望它只为每条消息生成一条消息(因此在第一次匹配后停止),您可以return;
在匹配一个单词并将消息发送给用户之后插入一个。
推荐阅读
- swift - 在 TableView 单元内滚动多个 CollectionView 单元
- javascript - 如何比较每个属性的不同对象之间的最大值并更新高度值?
- css - 将 contenteditable div 中的整个单词移动到下一行,以防没有位置
- amazon-web-services - 从 s3 事件触发获取 Lambda 中的输入
- jpa - JPA 与根实体的辅助表一对一
- java - 读入部分 InputStream
- javascript - 如何从Javascript中的字符串替换这个特殊字符
- java - java.lang.IllegalStateException: 更新 Spring Batch 到 4.1.1 后必须提供 ItemWriter
- java - 语音助手应用程序在反应本机(最好)或 Java 中替换 Google 助手
- omnet++ - 将数据包发送到相邻节点并在 Castalia Simulator 中使用多跳路由