我假设您已经有一种将命令与命令内容分开的技术 - 如果我误解了那部分,请纠正我。
一旦您将命令本身与内容分开,您将得到一个类似于以下内容的字符串:
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
getMatch(target) 如果未找到 ID,则返回 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} 的存在,方法是使用正则表达式,或者将用户名拆分为 #,并确保你得到两部分,并且第二部分只包含数字:
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 到9999 的范围内。无论哪种方式,它总是有 4 位数字。请注意,转换为 long 会丢失任何前缀 0,因此请坚持使用字符串进行验证。如果你运行这个验证,你需要对用户名运行它,不是昵称(昵称可以包含#,用户名不能)