Exemplo n.º 1
0
        ///////////////////////////////////////////////////////////////////////

        private static void HandleSubSpecOtherEscapeOrMetaChar(
            Match match,           // current Regex match, if any.
            StringBuilder builder, // [regsub] subSpec, partially translated.
            bool quote,            // use list element quoting?
            bool strict,           // strict conformance to the Tcl docs.
            char character,        // current character within "text".
            char nextCharacter     // next character within "text".
            )
        {
            //
            // NOTE: Is this a backslash followed by a digit?  If so, we
            //       need to append the applicable match group value, if
            //       any.
            //
            if (StringOps.CharIsAsciiDigit(nextCharacter))
            {
                if (match != null)
                {
                    //
                    // NOTE: What is the match group being used?
                    //
                    int groupIndex = nextCharacter - Characters.Zero;

                    //
                    // NOTE: Is the specified match group within the
                    //       available ones?
                    //
                    GroupCollection groups = match.Groups;

                    if ((groups != null) &&
                        (groupIndex >= 0) && (groupIndex < groups.Count))
                    {
                        //
                        // NOTE: Grab the specified match group and then
                        //       make sure its valid.
                        //
                        Group group = groups[groupIndex];

                        if (group != null)
                        {
                            //
                            // NOTE: Append the value of the match group,
                            //       quoting it if requested.
                            //
                            string matchValue = group.Value;

                            builder.Append(quote ?
                                           Parser.Quote(matchValue) : matchValue);
                        }
                    }
                }
                else
                {
                    //
                    // NOTE: We hit a properly escaped subSpec, insert
                    //       its .NET Framework equivalent, which will
                    //       include a dollar sign prefix.  An example
                    //       is "\1" to "$1".
                    //
                    builder.Append(
                        Characters.DollarSign.ToString() +
                        nextCharacter.ToString());
                }
            }
            else
            {
                if (strict)
                {
                    //
                    // BUGFIX: No, we do not actually want to do that.
                    //         Even though this portion of the subSpec
                    //         pattern argument handling for [regsub] is
                    //         poorly specified in the Tcl documentation,
                    //         what we actually need to do here is insert
                    //         a literal backslash followed by the literal
                    //         character we just encountered.
                    //
                    //         The exact rule is as follows:
                    //
                    //         "Any backslash in the subSpec pattern
                    //          argument NOT followed by an ampersand,
                    //          a single decimal digit, or another
                    //          backslash is treated as a literal
                    //          backslash."
                    //
                    //         As a consequence of the above rule, any
                    //         backslash followed by any character NOT
                    //         covered by the above rule will be inserted
                    //         into the output string literally.
                    //
                    builder.Append(character);
                    builder.Append(nextCharacter);
                }
                else
                {
                    //
                    // NOTE: We hit an "escaped" character that we do not
                    //       recognize, just insert it unescaped.
                    //
                    builder.Append(nextCharacter);
                }
            }
        }