public OrdinalityPatternMatcher(Ordinality ordinality, IEnumerable <PatternMatcher> patternMatchers, int maxMatches = Byte.MaxValue) { this.MaxMatches = maxMatches; this.Ordinality = ordinality; PatternMatchers.AddRange(patternMatchers.OrderBy(p => p.ContainsWildcard())); }
/// <summary> /// /// </summary> /// <param name="pattern">pattern to parse</param> /// <returns></returns> public PatternMatcher Parse(string pattern, bool defaultFuzzyMatch = false, Ordinality ordinality = Ordinality.One, int maxMatches = 16) { OrdinalityPatternMatcher ordinalityPatternMatcher = new OrdinalityPatternMatcher(ordinality, maxMatches); SequencePatternMatcher sequence = new SequencePatternMatcher(); StringBuilder sb = new StringBuilder(); var fuzzyMatch = defaultFuzzyMatch; var chars = pattern.GetEnumerator(); while (chars.MoveNext()) { char ch = chars.Current; bool repeatChar; do { repeatChar = false; switch (ch) { case '(': Ordinality modifierOrdinality = Ordinality.One; AddTextToSequence(sequence, sb, fuzzyMatch); var subText = GetPatternGroup(chars).Trim(); bool inModifiers = true; while (inModifiers && chars.MoveNext()) { ch = chars.Current; switch (ch) { case '~': fuzzyMatch = !defaultFuzzyMatch; break; case '?': modifierOrdinality = Ordinality.ZeroOrOne; break; case '+': modifierOrdinality = Ordinality.OneOrMore; break; case '*': modifierOrdinality = Ordinality.ZeroOrMore; break; default: if (byte.TryParse(ch.ToString(), out byte num)) { maxMatches = num; } else { var patternMatcher = Parse(subText, fuzzyMatch, modifierOrdinality, maxMatches); sequence.PatternMatchers.Add(patternMatcher); // break out of modifier loop inModifiers = false; repeatChar = true; } break; } } if (inModifiers) { // paren was end of string. var patternMatcher = Parse(subText, fuzzyMatch, modifierOrdinality, maxMatches); sequence.PatternMatchers.Add(patternMatcher); } maxMatches = 16; fuzzyMatch = defaultFuzzyMatch; break; case '|': { AddTextToSequence(sequence, sb, fuzzyMatch); if (sequence.PatternMatchers.Count == 1) { ordinalityPatternMatcher.PatternMatchers.Add(sequence.PatternMatchers.Single()); } else { ordinalityPatternMatcher.PatternMatchers.Add(sequence); } sequence = new SequencePatternMatcher(); } break; default: sb.Append(ch); break; } } while (repeatChar); } AddTextToSequence(sequence, sb, fuzzyMatch); if (sequence.PatternMatchers.Any()) { if (sequence.PatternMatchers.Count == 1) { ordinalityPatternMatcher.PatternMatchers.Add(sequence.PatternMatchers.Single()); } else { ordinalityPatternMatcher.PatternMatchers.Add(sequence); } } // if this is a oneOf, maxMatches with a single pattern matcher, just the inner patternmatcher. PatternMatcher result = ordinalityPatternMatcher; if (ordinalityPatternMatcher.PatternMatchers.Count == 1 && ordinalityPatternMatcher.Ordinality == Ordinality.One) { result = ordinalityPatternMatcher.PatternMatchers.Single(); } // if it is a sequence with only one patternMatcher, just the inner patternmatcher if (result is SequencePatternMatcher spm && spm.PatternMatchers.Count == 1) { result = spm.PatternMatchers.Single(); } return(result); }
public OrdinalityPatternMatcher(Ordinality ordinality, int maxMatches = Byte.MaxValue) { this.MaxMatches = maxMatches; this.Ordinality = ordinality; }