コード例 #1
0
ファイル: StringMatcher.cs プロジェクト: deloyar/PPL
        /// <summary>
        /// Compare the source against the pattern and if successfull returns a StringMatch
        ///
        /// There match is done against the source which can contain the wildcard '*'
        /// </summary>
        private StringMatch buildWithWildcards(string source)
        {
            StringMatch res = new StringMatch
            {
                Text          = source,
                Segments      = new List <string>(),
                StartsOnMatch = false,
            };

            string pattern = (string)m_pattern;
            string lsource = source.ToLower();

            int iP = 0, iS = 0, icP = -1, icS = -1;
            int ioS1 = -1, ioS2 = -1;
            int NP = pattern.Length, NS = source.Length;

            // skip all the starting characters untils we either don't match or reach a '*'
            while ((iP != NP) && (iS != NS) && (pattern[iP] != '*'))
            {
                if (lsource[iS] != pattern[iP])
                {
                    // mismatch
                    return(null);
                }
                iS++;
                iP++;
            }

            if (iS != 0)
            {
                addChunkToStringMatch(res, source.Substring(0, iS), true);
            }

            if (iP != NP)
            {
                // we have not finished parsing

                // now we start from a '*'
                // we try to get a sequence of matches to ('*', non '*'s), ('*', non '*'s), ....
                while (iS != NS)
                {
                    if (pattern[iP] == '*')
                    {
                        // we have reached a new '*', we will now compare against the next pattern character
                        iP++;
                        if (iP == NP)
                        {
                            //we have matched all the pattern
                            break; // while
                        }
                        if (icP != iP)
                        {
                            // this is the 1st time we try to process this '*'
                            if (icP >= 0)
                            {
                                // not the first run
                                // so we have successfully processed the previous '*'
                                if (ioS1 != ioS2)
                                {
                                    addChunkToStringMatch(res, source.Substring(ioS1, ioS2 - ioS1), false);
                                }
                                if (ioS2 != iS)
                                {
                                    addChunkToStringMatch(res, source.Substring(ioS2, iS - ioS2), true);
                                }
                            }
                            ioS1 = iS;
                            ioS2 = -1;
                        }
                        // we save the current position in case the '*' needs to match more characters
                        icP = iP;
                        icS = iS + 1;
                    }
                    else if (lsource[iS] == pattern[iP])
                    {
                        // if we were processing a '*', we now have a successfull match
                        // we are still matching sucessfully the pattern
                        if (ioS2 == -1)
                        {
                            ioS2 = iS;
                        }
                        iS++;
                        iP++;
                    }
                    else
                    {
                        // we have a mismatch
                        // let's try again with '*' matching one more character
                        iP = icP;
                        iS = icS++;
                    }
                    if (iP == NP)
                    {
                        //we have matched all the pattern
                        break; // while
                    }
                }
                // we have processed either the whole source or either the whole pattern
                // let's process any remaining '*' which here matches the empty string
                while ((iP != NP) && (pattern[iP] == '*'))
                {
                    iP++;
                }
            }
            if (iP == NP)
            {
                // we have a match!
                if (icP != iP)
                {
                    if (ioS1 != -1)
                    {
                        if (ioS2 == -1)
                        {
                            addChunkToStringMatch(res, source.Substring(ioS1, iS - ioS1), false);
                        }
                        else
                        {
                            if (ioS2 != ioS1)
                            {
                                addChunkToStringMatch(res, source.Substring(ioS1, ioS2 - ioS1), false);
                            }
                            if (ioS2 != iS)
                            {
                                addChunkToStringMatch(res, source.Substring(ioS2, iS - ioS2), true);
                            }
                        }
                    }
                }
                if (iS != NS)
                {
                    addChunkToStringMatch(res, source.Substring(iS, NS - iS), false);
                }
                return(res);
            }
            return(null);
        }