/// <summary> /// Retrieve all rules that match this string /// </summary> /// <param name="str">input string</param> /// <returns>list of rule items</returns> public List <MatchingRuleOutput> Retrieve(string str) { if (string.IsNullOrEmpty(str)) { throw new ArgumentNullException(nameof(str)); } if (Perfect.TryGetValue(str, out var ret)) { return(ret.ToRuleOutputs()); } // Fetch rule candidates var candidates = new List <MatchingRuleItem>(); for (var i = 0; i < str.Length; i++) { for (var j = 0; j < Math.Min(MaxIndexLen, str.Length - i); j++) { var key = str.Substring(i, j + 1); if (RuleItems.TryGetValue(key, out var rules)) { candidates.AddRange(rules); } } } // Further check if rule matches or not var matches = new List <MatchingRuleItem>(); foreach (var candidate in candidates) { if (candidate.KeyWords.All(str.Contains)) { matches.Add(candidate); } } return(matches.ToRuleOutputs()); }
/// <summary> /// Add matching rule /// </summary> /// <param name="matchingRuleItem"></param> public void Add(MatchingRuleItem matchingRuleItem) { switch (matchingRuleItem.Type) { case MatchingRuleType.Perfect: var key = matchingRuleItem.KeyWords[0]; if (!Perfect.TryGetValue(key, out var list)) { list = new List <MatchingRuleItem>(); Perfect[key] = list; } list.Add(matchingRuleItem); break; case MatchingRuleType.Contain: var indexKeyWord = ""; foreach (var keyword in matchingRuleItem.KeyWords) { if (indexKeyWord.Length < keyword.Length) { indexKeyWord = keyword; } } var indexKey = indexKeyWord.Substring(0, Math.Min(indexKeyWord.Length, MaxIndexLen)); if (!RuleItems.TryGetValue(indexKey, out var containRuleItems)) { containRuleItems = new List <MatchingRuleItem>(); RuleItems[indexKey] = containRuleItems; } containRuleItems.Add(matchingRuleItem); break; default: break; } }
/// <summary> /// Add matching rule /// </summary> /// <param name="matchingRuleItem"></param> public void Add(MatchingRuleItem matchingRuleItem) { var keywords = matchingRuleItem.KeyWords.SplitPatterns().ToList(); switch (matchingRuleItem.Type) { case MatchingRuleType.Perfect: var key = keywords.First(); if (!key.IsPattern()) { if (!Perfect.TryGetValue(key, out var list)) { list = new List <MatchingRuleItem>(); Perfect[key] = list; } list.Add(matchingRuleItem); } else if (PatternToPhrases.TryGetValue(key, out var phrases)) { foreach (var phrase in phrases) { if (!Perfect.TryGetValue(phrase, out var list)) { list = new List <MatchingRuleItem>(); Perfect[phrase] = list; } list.Add(matchingRuleItem); } } else { throw new KeyNotFoundException($"Pattern={key} is not found"); } break; case MatchingRuleType.Pattern: case MatchingRuleType.Contain: var indexKeyWord = keywords.First(); foreach (var keyword in keywords.Skip(1)) { if (!keyword.IsPattern()) { if (indexKeyWord.IsPattern()) { indexKeyWord = keyword; } else { if (indexKeyWord.Length < keyword.Length) { indexKeyWord = keyword; } } } } if (!indexKeyWord.IsPattern()) { var indexKey = indexKeyWord.Substring(0, Math.Min(indexKeyWord.Length, MaxIndexLen)); if (!RuleItems.TryGetValue(indexKey, out var containRuleItems)) { containRuleItems = new List <MatchingRuleItem>(); RuleItems[indexKey] = containRuleItems; } containRuleItems.Add(matchingRuleItem); } else if (PatternToPhrases.TryGetValue(indexKeyWord, out var phrases)) { foreach (var phrase in phrases) { var indexKey = phrase.Substring(0, Math.Min(phrase.Length, MaxIndexLen)); if (!RuleItems.TryGetValue(indexKey, out var list)) { list = new List <MatchingRuleItem>(); RuleItems[indexKey] = list; } list.Add(matchingRuleItem); } } else { throw new KeyNotFoundException($"Pattern={indexKeyWord} is not found"); } break; } }
/// <summary> /// Retrieve all rules that match this string /// </summary> /// <param name="str">input string</param> /// <returns>list of rule items</returns> public List <MatchingRuleOutput> Retrieve(string str) { if (string.IsNullOrEmpty(str)) { throw new ArgumentNullException(nameof(str)); } if (Perfect.TryGetValue(str, out var ret)) { return(ret.ToRuleOutputs()); } // Fetch rule candidates var candidates = new List <MatchingRuleItem>(); for (var i = 0; i < str.Length; i++) { for (var j = 0; j < Math.Min(MaxIndexLen, str.Length - i); j++) { var key = str.Substring(i, j + 1); if (RuleItems.TryGetValue(key, out var rules)) { candidates.AddRange(rules); } } } candidates = candidates.OrderBy(x => { return(x.Type == MatchingRuleType.Pattern ? 0 : 1); }).ToList(); // Further check if rule matches or not var matches = new List <MatchingRuleOutput>(); foreach (var candidate in candidates) { var keywords = candidate.KeyWords.SplitPatterns().ToList(); switch (candidate.Type) { case MatchingRuleType.Contain: var patternMatches1 = keywords.Select(keyword => { if (!keyword.IsPattern()) { return(str.Contains(keyword) ? keyword : null); } else if (PatternToPhrases.TryGetValue(keyword, out var phrases)) { return(phrases.FirstOrDefault(x => str.Contains(x))); } return(null); }); if (!patternMatches1.Any(x => x == null)) { matches.Add(candidate.ToRuleOutput(patternMatches1)); } break; case MatchingRuleType.Pattern: var patternMatches2 = PatternMatches(str, keywords); if (patternMatches2.Any()) { matches.Add(candidate.ToRuleOutput(patternMatches2)); } break; default: break; } } return(matches); }