Можно ли получить определенную часть регулярного выражения, которая соответствует строке

У меня есть регулярное выражение с большим количеством частей. пример:

var match = Regex.match("variablestring","(variabe|variables|stringvariable|strink|variablestring|varstrings)");

Мой реальный пример имеет гораздо больше с гораздо более тонкими различиями.

Мне нужен способ узнать, какая часть моего регулярного выражения сработала. Как в этом случае = "(variabe|variables|stringvariable|strink|variablestring|varstrings)" Я хочу, чтобы Regex или другая часть кода сообщала мне, что |variablestring| была частью регулярного выражения, которая получила результат. меня не волнует сам вывод, я хочу знать, какая часть REGEX была причиной, по которой я получил совпадение Есть ли способ?

Я смотрел по-разному и искал какой-то метод или свойство, но я не нашел ничего конкретного, что могло бы мне помочь, у кого-нибудь есть идеи?

Этот вопрос задавали и на него много раз отвечали на этом сайте, но в основном то, что вы хотите сделать, это сначала поставить более длинные термины в чередовании, то есть использовать: (variablestring|variables|variable|stringvariable|string|var‌​strings)

Tim Biegeleisen 21.11.2022 16:35

Нет, это не то, что я хочу, я хочу получить конкретную часть регулярного выражения, которая попала в мою строку

LoReyat 21.11.2022 16:37

Пожалуйста, отредактируйте свой пост с конкретным примером, включая входные данные, шаблон и ожидаемые результаты. Включение вашей попытки также было бы полезно.

gunr2171 21.11.2022 16:40
'one' -match '(?:(?<matched_one>one)|(?<matched_two>two))'
JohnLBevan 21.11.2022 17:00

Интересно, что это?

LoReyat 21.11.2022 17:04

Извините - опубликовал мой комментарий как PowerShell - см. ответ для С#

JohnLBevan 21.11.2022 17:07

Пс. variablestring не попал, так как variable совпало первым, поэтому другие варианты никогда не оценивались. Если вы хотите сопоставить полное слово, вам нужно проверить ^variablestring$ (т.е. ^ = начало строки, $ = конец строки; это означает, что между ними должна существовать вся строка. Чтобы сделать это для всех слов: `"^ (?:(?<variable>variabe)|(?<variables>variables)|(?<string‌​variable>stringvaria‌​ble)|(?<strink>strin‌​k)|(?<variablestring‌​>variablestring)| (?<‌​varstrings>varstring‌​s))$";

JohnLBevan 21.11.2022 17:25
Как настроить Tailwind CSS с React.js и Next.js?
Как настроить Tailwind CSS с React.js и Next.js?
Tailwind CSS - единственный фреймворк, который, как я убедился, масштабируется в больших командах. Он легко настраивается, адаптируется к любому...
LeetCode запись решения 2536. Увеличение подматриц на единицу
LeetCode запись решения 2536. Увеличение подматриц на единицу
Увеличение подматриц на единицу - LeetCode
Переключение светлых/темных тем
Переключение светлых/темных тем
В Microsoft Training - Guided Project - Build a simple website with web pages, CSS files and JavaScript files, мы объясняем, как CSS можно...
Отношения &quot;многие ко многим&quot; в Laravel с методами присоединения и отсоединения
Отношения &quot;многие ко многим&quot; в Laravel с методами присоединения и отсоединения
Отношения "многие ко многим" в Laravel могут быть немного сложными, но с помощью Eloquent ORM и его моделей мы можем сделать это с легкостью. В этой...
В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Карта дорог Беладжар PHP Laravel
Карта дорог Беладжар PHP Laravel
Laravel - это PHP-фреймворк, разработанный для облегчения разработки веб-приложений. Laravel предоставляет различные функции, упрощающие разработку...
0
7
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Приведенный ниже код должен помочь.

void Main()
{
    // note: the names can differ from the matched value; I kept them the same so it's obvious which value they relate to
    var pattern = "(?<variable>variabe)|(?<variables>variables)|(?<stringvariable>stringvariable)|(?<strink>strink)|(?<variablestring>variablestring)|(?<varstrings>varstrings)";

    var stringToTest = "variablestring";
    var match = Regex.Match(stringToTest,pattern);

    var nameOfMatchGroup = 
        match
        .Groups
        .Cast<Group>()
        .Where(x => x.Success && (x.Name != "0"))
        .First()
        .Name;

    Console.WriteLine(nameOfMatchGroup);
}

Шаблон регулярного выражения "(?<variable>variabe)|(?<variables>variables)|(?<stringvariable>stringvariable)|(?<strink>strink)|(?<variablestring>variablestring)|(?<varstrings>varstrings).

Здесь используется нечто, называемое именованными группами захвата: (?<name>pattern), где name — имя группы, а pattern — шаблон регулярного выражения содержимого этой группы. Для получения дополнительной информации см. Документацию MS

Затем я использовал Linq для фильтрации различных захватов в группе, чтобы найти тот, который соответствует (Success = true), игнорируя тот, у которого есть Name = 0, поскольку это целое выражение, а не группу захвата с именем дочернего элемента. Затем я беру первый из элементов, которые соответствуют этим условиям (в этом случае будет только один, как если бы несколько шаблонов соответствовали, они были разделены вертикальной чертой; поэтому, как только один соответствует, другие возможные совпадения в этом наборе игнорируются, поскольку эта часть строка уже проверена), затем получите Name этой группы захвата.

Заявление Cast связано с тем, что GroupCollection (тип match) не реализует IEnumerable; поэтому, чтобы использовать Linq поверх него, нам сначала нужно преобразовать его.

Другие вопросы по теме