首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有办法在不和谐的信息中找到一个单词的确切字符串?

有没有办法在不和谐的信息中找到一个单词的确切字符串?
EN

Stack Overflow用户
提问于 2020-08-29 19:15:16
回答 2查看 6.8K关注 0票数 5

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

这是我的filter.txt:

代码语言:javascript
复制
sad
sadness
sadnesses

因为“悲伤”也可以在“悲伤”中找到,所以每当写“悲伤”时,我都会得到“悲伤”的假阳性。

是否可能只检测消息中的确切字符串?就像:I want to be happy, because sadness is bad→‘只是发现悲伤’

我希望你能理解我的意思。

代码:

代码语言:javascript
复制
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) {}
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-30 12:21:55

正如红衣主教莫妮卡和哈迪斯已经说过的,你应该看看regex。

“‘Regex”表示“正则表达式”,并描述字符串的搜索模式。

您可以使用regex做很多事情,所以如果您想了解更多关于regex的信息,请查看教程

(这是我在谷歌搜索时第一次发现,你当然可以使用任何你喜欢的教程。)

对于您的用例,我建议如下:

首先,不要使用String.contains(),因为它只适用于String,而不是regex。

与以下正则表达式一起使用String.matches()

代码语言:javascript
复制
"(?is).*\\bSTRING\\b.*"

因为有一些逃逸操作,所以没有正则表达式,这就是它的样子:

代码语言:javascript
复制
(?is).*\bSTRING\b.*

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

\b

\b匹配一个单词边界。单词是a - zA - Z0 - 9_.这个字符的任何组合都被认为是一个单词。

这样做的好处是,在以下情况下,您可以匹配“悲伤”一词:

  • “我很难过。”句子末尾的.→并不影响检测。
  • “悲伤是我的事”→这个词是匹配的,即使它是第一个。(这也受到.*的影响。)

当使用“悲伤”时,它将与“悲伤”一词不相匹配,因为“悲伤”一词随后会继续使用:

  • “我感到悲伤!”→因为这个词没有结束在“悲伤”之后,这是不匹配的。匹配“悲伤”就行了。

.*

.匹配除某些换行符以外的任何字符。((?s)在这里帮助我。)

*基本上说,它前面的部分发生0次或更多次。

通过在字符串前后使用.*,正则表达式可以用于字符串周围的任何字符或字符组合(包括没有字符)。

这一点很重要,因为这样的话,单词就可以放在每个可以想象的句子中,而且无论发生什么事情,总是匹配的。

(?is)

?i?s启用了某些模式。

?i使正则表达式不敏感。这意味着,不管是悲伤,悲伤还是悲伤,这三者都会匹配。

?s启用了“单行模式”,这仅仅意味着.也匹配所有的换行。

?i?s可以组合成(?is),然后放在正则表达式的前面。

STRING不同,您只需插入这样的单词:

代码语言:javascript
复制
"(?is).*\\b" + line + "\\b.*"

您的代码最终将如下所示:

代码语言:javascript
复制
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;

票数 2
EN

Stack Overflow用户

发布于 2020-08-31 09:18:52

您也可以尝试使用字符串搜索算法(如阿霍-科拉西克 ),但这需要实现一个正确的签名表。这样的算法在一个更大的单词列表中会更好。

请注意,这样的算法很容易被绕过。简单地添加空格或使用1337字符替换会比简单的单词筛选器更聪明。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63650860

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档