Быстрая деконструкция Regex

Быстрая деконструкция Regex


Описание

У меня есть результат Regex-а Match match, группы которой я хочу разобрать на части вот так:

  • первую группу пропустить,
  • вторую группу присвоить к переменной instruction,
  • все остальные присвоить к переменной args.

В JavaScript это выглядело бы так:

const match = /example/.exec(`example`);
if (match === null) return;
const [, instruction, ...args] = match;

Хотел бы сделать такую же деконструкцию и в C#:

Match match = new Regex(@"example").Match("example");
if (!match.Success) return;
(_, Group instruction, Group[] ..args) = match.Groups;

Вопрос

Слышал, что в последних версиях C# появилось много синтаксического сахара и даже оператор ... Попробовал, везде получил ошибку.

Как все-таки выполнить эту деконструкцию?




Можно использовать именованные группы. Группа указывается через (?<НазваниеГруппы>метасимволы), пример (?<FirstWord>\\w+)\\s(?<SecondWord>\\w+) — непрерывное количество алфавитно-цифровых символов (не менее одного), потом идёт пробел, потом тоже любое непрерывное количество алфавитно-цифровых символов (не менее одного). Обращение к группе происходит через индексатор, принимающий строковый параметр у GroupCollection (свойство Groups). Пример кода:

var regex = new Regex("(?<FirstWord>\\w+)\\s(?<SecondWord>\\w+)");
var match = regex.Match(@"ПервоеСлово ВтороеСлово");

if (match.Success)
{
    var firstWord = match.Groups["FirstWord"].Value;
    var secondWord = match.Groups["SecondWord"].Value;
    Console.WriteLine(firstWord);
    Console.WriteLine(secondWord);
}
else
{
    Console.WriteLine("Неудача");
}

Можно ещё даже так, из-за перегруженной версии метода ToString у класса Capture:

var regex = new Regex("(?<FirstWord>\\w+)\\s(?<SecondWord>\\w+)");
var match = regex.Match(@"ПервоеСлово ВтороеСлово");

if (match.Success)
{
    Console.WriteLine(match.Groups["FirstWord"]);
    Console.WriteLine(match.Groups["SecondWord"]);
}

По поводу деконструирования объекта, у класса GroupCollection не определён метод Deconstruct, поэтому нет возможности сделать то, что вы хотите. Если хочется сделать какой-то кастом, то это будет костыль, и он будет выглядеть вот так:

static void Main(string[] args)
{
    var regex = new Regex("(?<FirstWord>\\w+)\\s(?<SecondWord>\\w+)");
    var match = regex.Match(@"ПервоеСлово ВтороеСлово");

    if (match.Success)
    {
        var (_, secondWord) = Deconstruct(match.Groups);
        Console.WriteLine(secondWord.Value);
    }
    else
    {
        Console.WriteLine("Неудача");
    }
}

private static (Capture, Capture) Deconstruct(GroupCollection groups)
{
    return (groups[1], groups[2]);
}





Report Page