简体   繁体   中英

Is it possible to get the specific part of a regex that matched the string

I have a regex, with a lot of parts. example:

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

My real example has a lot more with a lot more subtle differences.

I need a way to know which part of my regex got a hit. Like in this case = "(variabe|variables|stringvariable|strink| variablestring |varstrings)" I want Regex or a diff part of code to tell me that |variablestring| was the part of the regex that got a hit. i dont care that much about the output itself, i want to know what part of the REGEX was the reason i got a match Is there a way?

i have looked at different ways, and looked for some method or property but i havent found anything specific that could help me, anyone any ideas?

The below code should do the trick.

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);
}

The regex pattern is "(?<variable>variabe)|(?<variables>variables)|(?<stringvariable>stringvariable)|(?<strink>strink)|(?<variablestring>variablestring)|(?<varstrings>varstrings) .

This uses something called Named Capture groups: (?<name>pattern) where name is the name of the group and pattern is the regex pattern of the contents of that group. For more see MS Documentation

I've then used Linq to filter through the various captures in the group to find the one which matched ( Success = true ), ignoring the one with Name = 0 as that's the whole expression, rather than the child named capture group. I then take the first of the items that match those conditions (in this case there will only be one, as though multiple patterns match they're delimitted by pipes; so once one matches other possible matches in that set are ignored as that part of the string has already been tested), then get the Name of that capture group.

The Cast statement is because GroupCollection (the type of match ) doesn't implement IEnumerable ; so to use Linq over it we first need to convert it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM