У меня есть регулярное выражение с большим количеством частей. пример:
var match = Regex.match("variablestring","(variabe|variables|stringvariable|strink|variablestring|varstrings)");
Мой реальный пример имеет гораздо больше с гораздо более тонкими различиями.
Мне нужен способ узнать, какая часть моего регулярного выражения сработала. Как в этом случае = "(variabe|variables|stringvariable|strink|variablestring|varstrings)" Я хочу, чтобы Regex или другая часть кода сообщала мне, что |variablestring| была частью регулярного выражения, которая получила результат. меня не волнует сам вывод, я хочу знать, какая часть REGEX была причиной, по которой я получил совпадение Есть ли способ?
Я смотрел по-разному и искал какой-то метод или свойство, но я не нашел ничего конкретного, что могло бы мне помочь, у кого-нибудь есть идеи?
Нет, это не то, что я хочу, я хочу получить конкретную часть регулярного выражения, которая попала в мою строку
Пожалуйста, отредактируйте свой пост с конкретным примером, включая входные данные, шаблон и ожидаемые результаты. Включение вашей попытки также было бы полезно.
'one' -match '(?:(?<matched_one>one)|(?<matched_two>two))'
Интересно, что это?
Извините - опубликовал мой комментарий как PowerShell - см. ответ для С#
Пс. variablestring не попал, так как variable совпало первым, поэтому другие варианты никогда не оценивались. Если вы хотите сопоставить полное слово, вам нужно проверить ^variablestring$ (т.е. ^ = начало строки, $ = конец строки; это означает, что между ними должна существовать вся строка. Чтобы сделать это для всех слов: `"^ (?:(?<variable>variabe)|(?<variables>variables)|(?<stringvariable>stringvariable)|(?<strink>strink)|(?<variablestring>variablestring)| (?<varstrings>varstrings))$";
Приведенный ниже код должен помочь.
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 поверх него, нам сначала нужно преобразовать его.
Этот вопрос задавали и на него много раз отвечали на этом сайте, но в основном то, что вы хотите сделать, это сначала поставить более длинные термины в чередовании, то есть использовать: (variablestring|variables|variable|stringvariable|string|varstrings)