Пример #1
0
            public void Push(char ch)
            {
                org.Append(ch);
                switch (ch)
                {
                case ':':
                    if (escape)
                    {
                        goto default;
                    }
                    if (first || lastPushedChar == '[')
                    {
                        wordBuilder = new StringBuilder();
                        subClass    = new CharacterClass();
                        subClass.Add(':');
                        firstInSubClass = true;
                    }
                    else
                    {
                        if (wordBuilder != null)
                        {
                            ConvertUnicodeCategory(wordBuilder.ToString());
                            wordBuilder = null;
                            subClass    = null;
                        }
                        else
                        {
                            goto default;
                        }
                    }
                    break;

                case '^':
                    if (first || firstInSubClass)
                    {
                        firstInSubClass = false;
                        negativeGroup   = true;
                        break;
                    }
                    goto default;

                case '{':
                    if (readUnicodeGroup)
                    {
                        return;
                    }
                    goto default;

                case '}':
                    if (readUnicodeGroup)
                    {
                        readUnicodeGroup = false;
                        unicodeGroups.Add(unicodeGroupBuilder.ToString());
                        unicodeGroupBuilder.Length = 0;
                        return;
                    }
                    goto default;

                case '[':
                    if (escape)
                    {
                        goto default;
                    }
                    PushLastChar();
                    break;

                case ']':
                    if (escape)
                    {
                        goto default;
                    }
                    break;

                case '\\':
                    if (escape || wordBuilder != null)
                    {
                        goto default;
                    }
                    escape = true;
                    break;

                case '-':
                    if (escape || first || wordBuilder != null)
                    {
                        goto default;
                    }
                    range = true;
                    break;

                default:
                    if (readUnicodeGroup)
                    {
                        unicodeGroupBuilder.Append(ch);
                        return;
                    }
                    if (escape)
                    {
                        PushLastChar();

                        switch (ch)
                        {
                        case 'w':                         // A word character ([a - zA - Z0 - 9_])
                            AddRange('a', 'z');
                            AddRange('A', 'Z');
                            AddRange('0', '9');
                            table ['_'] = negativeGroup ? -1 : 1;
                            break;

                        case 'W':                         // A non-word character ([^a-zA-Z0-9_]).
                            for (int i = 0; i < table.Length; i++)
                            {
                                if ('0' <= i && i <= '9')
                                {
                                    continue;
                                }
                                if ('a' <= i && i <= 'z')
                                {
                                    continue;
                                }
                                if ('A' <= i && i <= 'Z')
                                {
                                    continue;
                                }
                                if (i == '_')
                                {
                                    continue;
                                }
                                table [i] = negativeGroup ? -1 : 1;
                            }
                            break;

                        case 'd':                         // A digit character ([0-9])
                            AddRange('0', '9');
                            break;

                        case 'D':                         // A non-digit character ([^0-9])
                            for (int i = 0; i < table.Length; i++)
                            {
                                if ('0' <= i && i <= '9')
                                {
                                    continue;
                                }
                                table [i] = negativeGroup ? -1 : 1;
                            }
                            break;

                        case 'h':                         // A hexdigit character ([0-9a-fA-F])
                            AddRange('0', '9');
                            AddRange('a', 'f');
                            AddRange('A', 'F');
                            break;

                        case 'H':                         // A non-hexdigit character ([^0-9a-fA-F])
                            for (int i = 0; i < table.Length; i++)
                            {
                                if ('0' <= i && i <= '9')
                                {
                                    continue;
                                }
                                if ('a' <= i && i <= 'f')
                                {
                                    continue;
                                }
                                if ('A' <= i && i <= 'F')
                                {
                                    continue;
                                }
                                table [i] = negativeGroup ? -1 : 1;
                            }
                            break;

                        case 's':                         // A whitespace character: /[ \t\r\n\f]/
                            table [' ']  = negativeGroup ? -1 : 1;
                            table ['\t'] = negativeGroup ? -1 : 1;
                            table ['\r'] = negativeGroup ? -1 : 1;
                            table ['\n'] = negativeGroup ? -1 : 1;
                            table ['\f'] = negativeGroup ? -1 : 1;
                            break;

                        case 'S':                         // A non-whitespace character: /[^ \t\r\n\f]/
                            for (int i = 0; i < table.Length; i++)
                            {
                                if (" \\t\\r\\n\\f".Contains((char)i))
                                {
                                    continue;
                                }
                                table [i] = negativeGroup ? -1 : 1;
                            }
                            break;

                        case 'a':
                            table ['\a'] = negativeGroup ? -1 : 1;
                            break;

                        case 'b':
                            table ['\b'] = negativeGroup ? -1 : 1;
                            break;

                        case 't':
                            table ['\t'] = negativeGroup ? -1 : 1;
                            break;

                        case 'r':
                            table ['\r'] = negativeGroup ? -1 : 1;
                            break;

                        case 'v':
                            table ['\v'] = negativeGroup ? -1 : 1;
                            break;

                        case 'f':
                            table ['\f'] = negativeGroup ? -1 : 1;
                            break;

                        case 'n':
                            table ['\n'] = negativeGroup ? -1 : 1;
                            break;

                        case 'p':
                            readUnicodeGroup = true;
                            break;

                        default:
                            lastChar = ch;
                            hasLast  = true;
                            PushLastChar();
                            break;
                        }

                        escape = false;
                        break;
                    }

                    if (wordBuilder != null)
                    {
                        wordBuilder.Append(ch);
                        subClass.Push(ch);
                        break;
                    }

                    if (!hasLast)
                    {
                        lastChar = ch;
                        hasLast  = true;
                        break;
                    }
                    if (range)
                    {
                        for (int i = (int)lastChar; i <= (int)ch; i++)
                        {
                            table [i] = negativeGroup ? -1 : 1;
                        }
                        hasLast = false;
                    }
                    else
                    {
                        PushLastChar();
                        lastChar = ch;
                        hasLast  = true;
                    }
                    range = false;
                    break;
                }
                first          = false;
                lastPushedChar = ch;
            }