Пример #1
0
        private string Process(
            string input,
            string replaceWith,
            IComparisonWithAdvance mainComparison,
            Dictionary <string, Capture> capturing,
            List <State> stateList,
            bool replace,
            out int numMatches,
            Func <RunState, string, int, string> ReplaceFunc = null,
            Action <RunState> InitRunState = null)
        {
            // The replaced string
            StringBuilder replaced = new StringBuilder();

            var runState = new RunState();

            if (InitRunState != null)
            {
                InitRunState(runState);
            }
            numMatches = 0;

            // Iterate the input string character by character
            for (int outerIndex = 0; outerIndex < input.Length;)
            {
                runState.Clear();
                runState.BeginPos = outerIndex;
#if DEBUG
                int dbgInitialOuterIndex = outerIndex;
                if (dbgInitialOuterIndex == 1374)
                {
                    Misc.Break();
                }
                string dbgInputPortion = input.Substring(dbgInitialOuterIndex,
                                                         Math.Min(20, input.Length - dbgInitialOuterIndex));
#endif
                //// All states enabled?
                int  afterState = outerIndex;
                bool stateEnabled;
                if (stateList != null)
                {
                    for (; ;)
                    {
                        // If the state becomes enabled, check that directly afterwards we don't encounter a close state
                        // Imagine we have a state which opens on '<%' and closes on '%>' and the input string is '<%%> ...'
                        // We enable then instantly disable again. We only stop trying to update the state when updating the
                        //  state doesn't advance the position
                        int curIndex = afterState;
                        stateEnabled = UpdateState(stateList, input, afterState, runState, out afterState);
                        if (curIndex == afterState)
                        {
                            // Updating the state did not advance the position - continue with the replace
                            break;
                        }
                    }
                }
                else
                {
                    stateEnabled = true;
                }

                // Copy the state string (if any)
                if (afterState != outerIndex)
                {
                    string stateString = input.Substring(outerIndex, afterState - outerIndex);
                    replaced.Append(stateString);
                }

                // Update the main index
                outerIndex = afterState;

                if (outerIndex < input.Length)
                {
                    bool matched = stateEnabled;
                    if (stateEnabled)
                    {
                        // Run the statements beginning from 'afterState'
                        int innerIndex = outerIndex;
                        int afterMatch;
                        matched = mainComparison.CompareAndAdvance(input, innerIndex, 0, runState, out afterMatch);
                        if (matched)
                        {
                            // The begin of the matching string
                            runState.BeginPos = outerIndex;

                            ++numMatches;

                            // This is a match! :)
                            // Do the replace
                            string iterReplaced = ReplaceMatch(replaceWith, ReplaceFunc, capturing, runState, input, afterMatch);
                            replaced.Append(iterReplaced);
                            LogMatchReplace(
                                input,
                                innerIndex,
                                afterMatch,
                                iterReplaced,
                                capturing);

                            // Update the outer index and continue iterating from there
                            outerIndex = afterMatch;
                        }
                    }

                    if (!matched)
                    {
                        if (replace)
                        {
                            // Match failed: copy this character to the output string and move on to the next one (if this is replace mode)
                            replaced.Append(input[outerIndex]);
                        }
                        ++outerIndex;
                    }
                }
            }
            return(replaced.ToString());
        }