我想为我的Discord机器人制作一个事件管理器功能,但我有一个问题需要解决。机器人使用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();
}
}
}
有有效的方法吗?也就是说,在单个命令行上读取不同类型的数据?
您可以做的一件事是使用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上找到了这个正则表达式,当我再次找到它时,将添加对它的引用