исправлен парсер команд
All checks were successful
CI / build-test (push) Successful in 32s
Release / pack-and-publish (release) Successful in 35s

This commit is contained in:
2025-12-07 10:50:58 +03:00
parent edc718b1f9
commit 67de9e197a
4 changed files with 32 additions and 21 deletions

View File

@@ -49,12 +49,10 @@ internal sealed class CommandsRegistry
var match = cmd.Pattern.Match(command);
if (match.Success)
{
// Собираем аргументы
// Собираем именованные группы (без числовых)
var args = cmd.Pattern.GetGroupNames()
.Where(n => n != "0")
.Select(n => new { n, v = match.Groups[n].Value })
.Where(x => !string.IsNullOrEmpty(x.v))
.ToDictionary(x => x.n, x => x.v);
.Where(n => !int.TryParse(n, out _))
.ToDictionary(n => n, n => match.Groups[n].Value);
task = cmd.Handler(ctx, args, ct);
return true;
@@ -64,14 +62,21 @@ internal sealed class CommandsRegistry
return false;
}
/// <summary>
/// Универсальный парсер шаблонов: /cmd {a} {b?} {c}
/// </summary>
private static Regex ToRegex(string template)
{
// Простейшее преобразование шаблона: "/open {page} {id?}" -> Regex
var escaped = Regex.Escape(template)
.Replace("\\{", "{").Replace("\\}", "}");
var pattern = "^" + escaped
.Replace("{page}", "(?<page>\\S+)")
.Replace("{id?}", "(?<id>\\S+)?") + "$";
var pattern = "^" + Regex.Replace(escaped, @"\{(\w+)(\?)?\}", m =>
{
var name = m.Groups[1].Value;
var optional = m.Groups[2].Success;
return optional ? $"(?<{name}>\\S+)?" : $"(?<{name}>\\S+)";
}) + "$";
return new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
}