首页 > 解决方案 > 如何使用 Discord JDA 在单个命令行上处理多个字符串和不同类型的数据?

问题描述

我想为我的 Discord 机器人创建一个事件管理器功能,但我有一个问题要解决。bot 使用 split() 方法读取每个字符串,从而执行命令。然而,有一天,我遇到了一个需要返回多个字符串的问题(例如,一个事件标题,它的长度可能会有所不同)。我设法使用 StringBuffer() 解决了问题,但我这样做的方式仅在此字符串序列之后没有其他类型的数据时才足够。split() 方法使创建命令变得更加容易,因为我可以使用索引,但是当我需要连接多个字符串并在之后使用其他类型的数据时,它会妨碍我。

目前,创建事件的命令总而言之,其工作原理如下:

$event title [Str title]
$event url [Str url]
$event slots [int slots]

我希望它如何工作:

$event '[Str title]' [Str url] [int slots]

如果标题由多个字符串组成,则它的开头和结尾必须有引号,并且里面的所有内容都是它的一部分。

这是我目前使用的代码示例:

public class EventManager extends ListenerAdapter {

private String title;

public void onGuildMessageReceived(GuildMessageReceivedEvent e) {
     
     String[] message = e.getMessage().getContentRaw().split(" ");
     EmbedBuilder eb = new EmbedBuilder();

     if (message[0].equalsIgnoreCase("$event") && message[1].equalsIgnoreCase("title")) {
        
         StringBuffer sb = new StringBuffer();
         for (int i  = 2; i < message.length; i++) {
            sb.append(message[i]);
            sb.append(" ");
         }
            
         this.title = sb.toString();
         
         eb.setColor(Color.GREEN);
         eb.setDescription("Title: " + title);
         e.getChannel().sendMessage(eb.build()).queue();

    }

}

}

有没有一种有效的方法来做到这一点?也就是说,在单个命令行上读取不同类型的数据?

标签: javadiscord-jda

解决方案


您可以做的一件事是使用 RegEx 拆分您的消息。如果您构造一个匹配用引号括起来的字符串的正则表达式,您可以使用它将初始字符串拆分为一个数组。使用该数组,您可以使用索引来引用您的首选参数。

我使用以下代码拆分我的消息:

private ArrayList<String> split(String subjectString){
    ArrayList<String> matchList = new ArrayList<>();
    Pattern regex = Pattern.compile("\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|'([^'\\\\]*(?:\\\\.[^'\\\\]*)*)'|[^\\s]+");
    Matcher regexMatcher = regex.matcher(subjectString);
    while (regexMatcher.find()) {
        if (regexMatcher.group(1) != null) {
            // Add double-quoted string without the quotes
            matchList.add(regexMatcher.group(1));
        } else if (regexMatcher.group(2) != null) {
            // Add single-quoted string without the quotes
            matchList.add(regexMatcher.group(2));
        } else {
            // Add unquoted word
            matchList.add(regexMatcher.group());
        }
    }
    return matchList;
}

因此,如果您传递$event 'Some title' a_url 2给该方法,您将收到一个 ArrayList: ["$event", "Some title", "a_url", "2"]。然后你只需要在需要时解析整数。

请注意,初始消息中的引号不包含在数组中

我在另一个 SO 上找到了这个正则表达式,当我再次找到它时会添加对它的引用。


推荐阅读