Esempio n. 1
0
        /// <summary>
        /// DoFind is the helper for a regular Find (no proximity).  Very simple logic:
        /// Given a Regex Match, it will iterate through the match adding matches to
        /// the OberservableConcurrentDictionary
        /// </summary>
        /// <param name="match">The regex match based on the Find box text value</param>
        /// <param name="startRange">The Paragraph's start range - we need this for highlighting</param>
        /// <param name="endRange">The Paragraph's end range - we need this for highlighting</param>
        /// <param name="observableResults">The concurrent dictionary we are writing results to</param>
        public static void DoFind(SysRegex.Match match,
                                  int startRange,
                                  int endRange,
                                  OCDictionary observableResults)
        {
            while (match.Success)
            {
                // get actual match start and end range locations
                var beginRangeMatch = startRange + match.Index;
                var endRangeMatch   = beginRangeMatch + match.Length;

                // get some context for the match
                var beginContext = beginRangeMatch >= 5 ? (beginRangeMatch - 5) : beginRangeMatch;
                var endContext   = (endRangeMatch + 5) < endRange ? (endRangeMatch + 5) : endRange;
                FinderHelpers.AddResults(beginRangeMatch, endRangeMatch, beginContext, endContext, observableResults);

                match = match.NextMatch();
            }
        }
Esempio n. 2
0
        /// <summary>
        /// DoFindProximity takes matches and decides if they are truly proximity based on
        ///  1. Stripping the match of special characters and extra whitespace
        ///  2. Splitting the match into a list based on whitespace
        /// Once we have a list, we can just walk through the X proximity words to see if a match
        /// exists.  This means you can't search for a word within X words of a hyphen.
        /// </summary>
        /// <param name="matches">Enumberable list of possible matches</param>
        /// <param name="startRange">The Paragraph's start range - we need this for highlighting</param>
        /// <param name="endRange">The Paragraph's end range - we need this for highlighting</param>
        /// <param name="searchKeyRegex">SearchKey</param>
        /// <param name="prox">Prox object, to tell us ProxRegKey, proximity, case sensitive, etc</param>
        /// <param name="observableResults">The concurrent dictionary we are writing results to</param>
        public static void DoFindProximity(IEnumerable <SysRegex.Match> matches,
                                           int startRange,
                                           int endRange,
                                           SysRegex.Regex searchKeyRegex,
                                           ProxSearchSettings prox,
                                           OCDictionary observableResults)
        {
            foreach (var match in matches)
            {
                //  so if our searchKey is "this " and the proxKey is "search", we will match the following with threshold = 5
                //  1. this sentence represents a search string that has a hit
                //      Match:  this.*search
                //  2. search string in this sentence
                //      Match:  search.*this

                //  first lets find our search key
                var searchKeyMatch = searchKeyRegex.Match(match.Value);

                while (searchKeyMatch.Success)
                {
                    var pKeyRegOpts            = prox.CaseSensitive ? SysRegex.RegexOptions.None : SysRegex.RegexOptions.IgnoreCase;
                    var proximityKeyRegex      = new SysRegex.Regex(prox.SearchKey, pKeyRegOpts);
                    var searchKeyMatchEndpoint = searchKeyMatch.Index + searchKeyMatch.Length;

                    //  so if our searchKey is "this " and the proxKey is "search", with a threshold = 5
                    //
                    //  1. this sentence represents a search string that has a hit
                    //     |   ||                     |    |       |
                    //      \ /  \                     \  /       /
                    //  searchKey \                  proxKey     /
                    //             \________afterWords__________/
                    //
                    //  2. search string in this sentence
                    //    ||    |          ||   ||       |
                    //    | \  /           | \ / |       |
                    //    | proxKey        |searchKey    |
                    //    \               /       \     /
                    //     \_beforeWords_/       afterWords

                    string beforeWords = FinderHelpers.GetProximityWords(match.Value.Substring(0, searchKeyMatch.Index), prox.WordThreshold, true);
                    string afterWords  = FinderHelpers.GetProximityWords(match.Value.Substring(searchKeyMatchEndpoint), prox.WordThreshold, false);

                    var beforeMatch = proximityKeyRegex.Match(beforeWords);
                    var afterMatch  = proximityKeyRegex.Match(afterWords);

                    var successPredicate = prox.LogicalNot
                                           ? (!beforeMatch.Success && !afterMatch.Success)
                                           : (beforeMatch.Success || afterMatch.Success);

                    while (successPredicate)
                    {
                        // Find where the match starts - before or after search key
                        int matchIndex = beforeMatch.Success
                            ? ((beforeWords.Length - beforeMatch.Index + 2) * -1)
                            : afterMatch.Success
                              ? afterMatch.Index + afterMatch.Length + 3
                              : 0;

                        int searchKeyIndex = startRange + match.Index + searchKeyMatch.Index;
                        int proxKeyIndex   = searchKeyIndex + matchIndex;
                        int startIndex     = searchKeyIndex < proxKeyIndex ? searchKeyIndex : proxKeyIndex;
                        int endIndex       = searchKeyIndex > proxKeyIndex ? searchKeyIndex : proxKeyIndex;

                        FinderHelpers.AddResults(startIndex, endIndex + searchKeyMatch.Length, observableResults);

                        // So, if we are searching IN proximity, then let's get all matches IN proximity
                        // both the before matches, AND the after matches
                        if (!prox.LogicalNot)
                        {
                            beforeMatch      = beforeMatch.NextMatch();
                            afterMatch       = afterMatch.NextMatch();
                            successPredicate = (beforeMatch.Success || afterMatch.Success);
                        }
                        // Otherwise, we found a match that is NOT in proximity (before/after) of the search word,
                        // so let's take it and break out of the loop (no need to search further...)
                        else
                        {
                            break;
                        }
                    }
                    searchKeyMatch = searchKeyMatch.NextMatch();
                }
            }
        }