How to read RegEx Captures in C#

前端 未结 3 928
耶瑟儿~
耶瑟儿~ 2020-11-28 15:18

I started a C# book and I decided to throw RegEx\'s into the mix to make the boring console exercises a little more interesting. What I want to do is ask a user for their ph

3条回答
  •  心在旅途
    2020-11-28 15:59

    Match results can be complicated to understand. I wrote this code to assist my understanding of what had been found and where. The intention is that pieces of the output (from the lines marked with //**) can be copied into the program to make use of values found in the match.

    public static void DisplayMatchResults(Match match)
    {
        Console.WriteLine("Match has {0} captures", match.Captures.Count);
    
        int groupNo = 0;
        foreach (Group mm in match.Groups)
        {
            Console.WriteLine("  Group {0,2} has {1,2} captures '{2}'", groupNo, mm.Captures.Count, mm.Value);
    
            int captureNo = 0;
            foreach (Capture cc in mm.Captures)
            {
                Console.WriteLine("       Capture {0,2} '{1}'", captureNo, cc);
                captureNo++;
            }
            groupNo++;
        }
    
        groupNo = 0;
        foreach (Group mm in match.Groups)
        {
            Console.WriteLine("    match.Groups[{0}].Value == \"{1}\"", groupNo, match.Groups[groupNo].Value); //**
            groupNo++;
        }
    
        groupNo = 0;
        foreach (Group mm in match.Groups)
        {
            int captureNo = 0;
            foreach (Capture cc in mm.Captures)
            {
                Console.WriteLine("    match.Groups[{0}].Captures[{1}].Value == \"{2}\"", groupNo, captureNo, match.Groups[groupNo].Captures[captureNo].Value); //**
                captureNo++;
            }
            groupNo++;
        }
    }
    

    A simple example of using this method, given this input:

    Regex regex = new Regex("/([A-Za-z]+)/(\\d+)$");
    String text = "some/directory/Pictures/Houses/12/apple/banana/"
                + "cherry/345/damson/elderberry/fig/678/gooseberry");
    Match match = regex.Match(text);
    DisplayMatchResults(match);
    

    The output is:

    Match has 1 captures
      Group  0 has  1 captures '/Houses/12'
           Capture  0 '/Houses/12'
      Group  1 has  1 captures 'Houses'
           Capture  0 'Houses'
      Group  2 has  1 captures '12'
           Capture  0 '12'
        match.Groups[0].Value == "/Houses/12"
        match.Groups[1].Value == "Houses"
        match.Groups[2].Value == "12"
        match.Groups[0].Captures[0].Value == "/Houses/12"
        match.Groups[1].Captures[0].Value == "Houses"
        match.Groups[2].Captures[0].Value == "12"
    

    Suppose that we want to find all matches of the above regular expression in the above text. Then we can use a MatchCollection in code such as:

    MatchCollection matches = regex.Matches(text);
    for (int ii = 0; ii < matches.Count; ii++)
    {
        Console.WriteLine("Match[{0}]  // of 0..{1}:", ii, matches.Count-1);
        RegexMatchDisplay.DisplayMatchResults(matches[ii]);
    }
    

    The output from this is:

    Match[0]  // of 0..2:
    Match has 1 captures
      Group  0 has  1 captures '/Houses/12/'
           Capture  0 '/Houses/12/'
      Group  1 has  1 captures 'Houses'
           Capture  0 'Houses'
      Group  2 has  1 captures '12'
           Capture  0 '12'
        match.Groups[0].Value == "/Houses/12/"
        match.Groups[1].Value == "Houses"
        match.Groups[2].Value == "12"
        match.Groups[0].Captures[0].Value == "/Houses/12/"
        match.Groups[1].Captures[0].Value == "Houses"
        match.Groups[2].Captures[0].Value == "12"
    Match[1]  // of 0..2:
    Match has 1 captures
      Group  0 has  1 captures '/cherry/345/'
           Capture  0 '/cherry/345/'
      Group  1 has  1 captures 'cherry'
           Capture  0 'cherry'
      Group  2 has  1 captures '345'
           Capture  0 '345'
        match.Groups[0].Value == "/cherry/345/"
        match.Groups[1].Value == "cherry"
        match.Groups[2].Value == "345"
        match.Groups[0].Captures[0].Value == "/cherry/345/"
        match.Groups[1].Captures[0].Value == "cherry"
        match.Groups[2].Captures[0].Value == "345"
    Match[2]  // of 0..2:
    Match has 1 captures
      Group  0 has  1 captures '/fig/678/'
           Capture  0 '/fig/678/'
      Group  1 has  1 captures 'fig'
           Capture  0 'fig'
      Group  2 has  1 captures '678'
           Capture  0 '678'
        match.Groups[0].Value == "/fig/678/"
        match.Groups[1].Value == "fig"
        match.Groups[2].Value == "678"
        match.Groups[0].Captures[0].Value == "/fig/678/"
        match.Groups[1].Captures[0].Value == "fig"
        match.Groups[2].Captures[0].Value == "678"
    

    Hence:

        matches[1].Groups[0].Value == "/cherry/345/"
        matches[1].Groups[1].Value == "cherry"
        matches[1].Groups[2].Value == "345"
        matches[1].Groups[0].Captures[0].Value == "/cherry/345/"
        matches[1].Groups[1].Captures[0].Value == "cherry"
        matches[1].Groups[2].Captures[0].Value == "345"
    

    Similarly for matches[0] and matches[2].

提交回复
热议问题