首页 > 解决方案 > 有没有办法在不和谐消息中找到单词的确切字符串?

问题描述

目前我正在开发一个不和谐的机器人,它正在过滤消息。我的问题是在尝试过滤包含在其他单词中的单词时出现的,从而触发重复消息。

这是我的 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) {}
}

标签: javadiscord-jda

解决方案


正如红衣主教 - 恢复莫妮卡哈迪斯已经说过的那样,你应该看看正则表达式。

“Regex”代表“正则表达式”,描述了字符串的搜索模式。

使用 regex 可以做很多事情,所以如果您想了解更多信息,请查看教程
(这是我在谷歌搜索时发现的第一个,当然你可以使用任何你喜欢的教程。)

对于您的用例,我建议以下内容:

首先,不要使用String.contains(),因为它只适用于字符串,而不适用于正则表达式。
改用String.matches()以下正则表达式:

"(?is).*\\bSTRING\\b.*"

因为做了一些转义,这就是没有它的正则表达式的样子:

(?is).*\bSTRING\b.*

我将解释它是如何工作的。

\b

\b匹配单词边界。单词字符是a- zA- Z0-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;在匹配一个单词并将消息发送给用户之后插入一个。


推荐阅读