public static MatchingRuleOutput ToRuleOutput(this MatchingRuleItem item, IEnumerable <string> patternKeywords = null)
        {
            var ret = JsonConvert.DeserializeObject <MatchingRuleOutput>(JsonConvert.SerializeObject(item));

            ret.Matches = patternKeywords?.ToList() ?? new List <string>();
            return(ret);
        }
        /// <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;
            }
        }