Discord Bot的命令处理

时间:2019-07-01 10:21:15

标签: java string parsing kotlin

我正在研究Discord Bot进行审核。我使用JDA库。我目前无法处理命令。

有4种命令方案:

".ban <@302390080104955904> advertising"
".ban <@!302390080104955904> advertising"
".ban 302390080104955904 advertising"
".ban et advertising"

当bot收到命令时,我会将命令和前缀放在子字符串中。

在第一种情况下,我想提取ID“ 302390080104955904”并将其从字符串中删除,这样我就知道了原因

第二种情况与第一种情况相同,但是在@之后有感叹号

在第三种情况下,我只需要提取ID并将其删除

在最后一种情况下,我只需要提供用户名并搜索用户即可。

我试图多次实现,但是我总是失败。 关于如何进行这项工作的任何想法

编辑:我接受Kotlin和Java答案

1 个答案:

答案 0 :(得分:3)

我假设您已经有一种将命令与命令内容分离的技术-如果我误解了该部分,请纠正我。

一旦命令本身与内容分开,您将得到类似于以下内容的字符串:

val commandContent = "<@!302390080104955904> advertising";

在这里,您需要将其拆分:

val cache = commandContent.split(" ", limit=2);

您现在拥有的是一个最大有两个大小的数组。

从那里开始,进一步解析它以保持数据清晰:

// Note: I haven't implemented any safety. If you get an unexpected size, you'll need to handle that yourself
val target = cache[0];
val reason = cache[1];

从这里开始,您可以使用正则表达式。在进入代码之前,让我解释一下正则表达式:

<?        - Attempt to match an opening bracket
@?        - Attempt to find @
!?        - Attempt to find !
([0-9]+)  - Constant: find a group of numbers
>?        - Attempt to find a closing bracket

这也有助于过滤出username#discriminator格式的用户名-任何非数字字符都将字符串识别为ID。您也可以在regex101.com上玩它。

从这里,您可以设置匹配项:

val regex = """<?@?!?([0-9]+)>?""".toRegex()
fun getMatch(target: String) : String? = regex.matchEntire(target)?.groups?.get(1)?.value
如果找不到ID,则

getMatch(target)返回null,否则返回ID作为字符串。

现在,您所需要做的就是调用方法并执行您想做的任何事情:

val match = getMatch(target); 
if (match != null) {
    // You have the UID. 
} else {
    // You have a username. Use `target` to retrieve the user ID. 
} 

虽然可行,但您需要牢记以下几点:关于用户名,您的示例仅包含用户名而没有区分符。如果您的漫游器加入了足够大的服务器,并且您遍历用户以查找具有匹配用户名的服务器,那么您可能会发现自己禁止输入错误的人,或者如果您忘记打破循环,则禁止使用该用户名的所有人。

如果我是您,则可以通过使用正则表达式或在#[0-9]{4}处拆分用户名来检查{​​{1}}是否存在,并确保获得两部分,而第二部分仅由数字组成:

#

鉴别符的范围是val split = target.split("#") if (split.size != 2) // Fail if (split[1].toLongOrNull() == null || split[1].length != 4 || split[1].contains("-")) // fail - non-number long, invalid discriminator (discriminators are always 4 digits), or negative discriminator 0001。无论哪种方式,它始终具有4位数字。请注意,到long的转换将丢失所有带前缀的0,因此请坚持使用字符串进行验证。而且,如果您运行此验证,则需要针对用户名()昵称(昵称可以包含9999,用户名不能)