/** Recursively traverse the tree collecting all matches from GroupTokens. */ private void buildMatch(Token root, RegexMatch accumulator) { if (root is GroupToken) { var group = root as GroupToken; if (group.Index >= 0) { accumulator.Groups.Add(group.Match); } foreach (Token t in group.Content) { buildMatch(t, accumulator); } } else if (root is QuantifierToken) { var quantifier = root as QuantifierToken; buildMatch(quantifier.Target, accumulator); } else if (root is OrToken) { var or = root as OrToken; foreach (Token t in or.Alternatives) { buildMatch(t, accumulator); } } }
/** Returns the first match found in the input. * * If there is no match, a RegexMatch will be returned whose * Success is set to false. * * \param input The input string. * \return The first match. If the match did not succeed, * RegexMatch.Success will be set to false. */ public RegexMatch Match(string input) { for (int i = 0; i < input.Length; i++) { int cursor = i; if (_root.Matches(input, ref cursor)) { var match = new RegexMatch(i, cursor, input); buildMatch(_root, match); return(match); } } return(new RegexMatch(0, 0, string.Empty, false)); }
/** Finds all the matches in the input. * * Overlapping matches will not be reported, so that "aaa", when * matched with "a+" will only produce one match (i.e. "aaa") and * not three (i.e. "aaa", "aa" and "a"). * * \param input The input string. * \return A sequence of RegexMatch. */ public IEnumerable <RegexMatch> Matches(string input) { // zero width matches can occur right after the last character for (int i = 0; i <= input.Length; i++) { int cursor = i; if (_root.Matches(input, ref cursor)) { var match = new RegexMatch(i, cursor, input); buildMatch(_root, match); yield return(match); /* jump over the whole match, but do not take a step back if the match has * * length zero (for example the pattern a* matches any string with a zero * * length match). * * * * (note that i will be incremented before the next iteration starts, thus we * * have to subract one or we will skip a character) */ i = Math.Max(cursor - 1, i); } } }