Я предполагаю, что у вас уже есть метод для отделения команды от ее содержимого - если я неправильно понял эту часть, пожалуйста, исправьте меня.
Как только вы отделите саму команду от содержимого, вы получите строку, похожую на:
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
- любой нечисловой символ распознает строку как не идентификатор. Вы также можете поиграть с ним на regex101.com .
Здесь вы можете установить соответствие:
val regex = """<?@?!?([0-9]+)>?""".toRegex()
fun getMatch(target: String) : String? = regex.matchEntire(target)?.groups?.get(1)?.value
getMatch(target)
возвращает ноль, если идентификатор не найден, и идентификатор в виде строки в противном случае.
Теперь все, что вам нужно сделать, это вызвать метод и делать все, что вы хотите:
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, поэтому придерживайтесь строк для проверки. И если вы запускаете эту проверку, вам нужно запустить ее для имени пользователя, , а не псевдонима (псевдонимы могут содержать #
, имена пользователей не могут)