Lupu5R3x Ответов: 2

Регулярное выражение match.name возвращает 0 а не имя группы захвата


Привет У меня есть это
// ... Input string.
            string input = "Left12345Right";

            // ... Use named group in regular expression.
            Regex expression = new Regex(@"Left(?<middle>\d+)Right");

            // ... See if we matched.
            Match match = expression.Match(input);
            if (match.Success)
            {
                // ... Get group by name.
                string result = match.Groups["middle"].Value;
                Console.WriteLine("Middle: {0}", result);
                Console.WriteLine(match.Name);
            }
            // Done.
            Console.ReadLine();

Когда я читаю информацию, .Name должен возвращать имя группы захвата, но для меня он возвращает только 0, и я не могу понять почему.

Так что я надеюсь, что кто-нибудь здесь сможет сказать мне, что я делаю не так. (Я новичок в C# и регулярных выражениях).

Овации
/LR

Что я уже пробовал:

Погуглил, чтобы найти ответ, но ничего не нашел.

Richard MacCutchan

Согласно моим тестам и документации, Match не содержит а Name собственность.

Richard MacCutchan

Компилятор отклонил его, когда я попытался. Я должен взглянуть на это подольше.

2 Ответов

Рейтинг:
8

Richard Deeming

Сам экземпляр Match эквивалентен первому объекту в коллекции, по крайней мере Match.Groups[0], который представляет собой весь матч.

Нет никакого разумного имени, которое можно было бы дать группе, представляющей весь матч, поэтому она получает это имя 0 по умолчанию. Это позволяет ссылаться на все совпадение в выражении замены с помощью $0.

Из вашего вопроса не ясно, чего вы пытаетесь достичь с помощью Name собственность. Ты что-то искал? метод GetGroupNames[^] вместо этого?


Maciej Los

5ed!

Lupu5R3x

Я пытаюсь преобразовать шаблон регулярного выражения Autoit следующим образом "(abc)|(def)|(ghi)", 1
Где, 1 возвращает совпадение массивов.

Таким образом, результат "def" вернет [0] = , [1] = def

Но поскольку я не смог найти ни одного эквитанта для сопоставления массивов в C#, я надеялся, что смогу использовать группы именования, чтобы вернуть имя группы, которая была сопоставлена.

например. (?abc)|(?<d>def)|(?<g>ghi) и тест def должен (была моя мысль) вернуть d.

Но когда я пытаюсь сделать то, что @OriginalGriff sugested, я просто получаю имя группы, которое я указал, поэтому [1] возвращает a, [2] = b, но это происходит независимо от того, что такое совпадение.

И да, я должен был точно указать, чего я пытаюсь достичь, с помощью регулярного выражения, sry для этого :(

/LR

Richard Deeming

Я не знаком с функцией "сопоставление массивов", но именованные группы кажутся мне подходящим способом:

Regex expression = new Regex(@"(?<a>abc)|(?<b>def)|(?<c>ghi)", RegexOptions.ExplicitCapture);
Match match = expression.Match(input);
if (match.Success)
{
    if (match.Groups["a"].Success)
    {
        // Matched first option...
    }
    else if (match.Groups["b"].Success)
    {
        // Matched second option...
    }
    else if (match.Groups["c"].Success)
    {
        // Matched third option...
    }
}

Lupu5R3x

Хм, Да, кажется, это было бы самое простое решение моей проблемы. :)

Независимо от того, как это раздражает, что все мои однострочные регулярные выражения заканчиваются несколькими строками В C#, чтобы получить тот же результат :( последнее регулярное выражение, которое я перевел, пошло от одной строки до 10 строк в C# :O конечно, C# не поддерживает \K :'(

/LR

Richard Deeming

Я не знаком с этим \K - это что, какой-то скрытый оператор?

Группировка конструкций в регулярных выражениях | Microsoft Docs[^]

string input = "2010 1999 1861 2140 2009";
string pattern = @"(?<=\b20)\d{2}\b";
foreach (Match match in Regex.Matches(input, pattern))
{
    Console.WriteLine(match.Value);
}

/*
Output:
10
09
*/

Lupu5R3x

\K "сбрасывает начало совпадения в текущей точке строки темы. Обратите внимание, что уже захваченные группы остаются в покое и все еще заполняют возвращаемый массив; поэтому всегда можно вернуться к ним позже. Действие \K похоже, но не идентично взгляду назад, в том, что \K может работать на чередованиях различной длины."

Так что это regreplace".{1,60}\K(\s{1,2}|$)", "\r\n"
который вернул одну строку, "разделенную" на 60 символов в одной строке сразу, в итоге получилось так.
струнный splitPattern = @"(.{1,60})(\s{1,2}|$)";
Поиск поиск = поиск.Параметром ignorecase;
Regex splitText = новое регулярное выражение(splitPattern, regexOptions);
Результат то StringBuilder новое окно инструментов();

foreach (Match match in splitText.Matches(input))
{
если (совпадение.Успех)
{
результат.Append(матч.Группы[0].значение + "\r\n");
}
}
возвращаемый результат.Метод toString();

/LR

Рейтинг:
2

OriginalGriff

Попробовать это:

Console.WriteLine(match.Groups[1].Name);
Первая группа в матче-это весь матч, который состоит из всех групп в матче.


Maciej Los

5ed!

Lupu5R3x

Привет, я пробовал это сделать, но [1] Просто дайте мне имя первой группы в моем шаблоне, а не имя захваченной группы.

например, если у меня есть этот паттерн (?(abc)|(?<d>def)|(?<g>ghi) и тестовая строка def [1] просто дает мне :(

/LR