是否可以在C开关/案例中使用正则表达式作为案例

时间:2015-02-13 19:09:19

标签: c regex switch-statement

“这是我试图实现的交换机块。这种方法是否可行。我找不到支持此文档的文档。它编译但不起作用。”

       'switch (ch)
    {   case '[";,(){}", ]': printf("\nSEPARATOR: %c found\n", ch);
                                ch =fgetc(fin);
                                break;
        case '[_|a-zA_Z]':
                        printf("\nIDENTIFIER: ");
                        identCh[i] = ch;
                        printf("%c",identCh[i]);
                        ch = fgetc(fin);
                        while(is_letter(ch)){
                            identCh[i++] = ch;
                            ch = fgetc(fin);
                            printf("%c",identCh[i]);}
                        break;
        case '[1-9]':
                        printf("\nINTEGER: ");
                        intCh[i] = ch;
                        printf("%c",intCh[i]);
                        ch = fgetc(fin);
                        while(is_digit(ch)){
                            intCh[i++] = ch;
                            printf("%c",intCh[i]);
                            ch = fgetc(fin);}
                        break;
       // case '':    break;
        default: printf("\nError");
                ch = fgetc(fin);
                break;'}

3 个答案:

答案 0 :(得分:2)

不,你不能将正则表达式用作C中的case语句。事实上,C对所有 * 的任何类型的正则表达式都没有内置支持。但是,如果使用“直通”扩展正则表达式,则可以在速度方面获得相同的结果:

switch (ch) {
    case '"';
    case ';':
    case ',':
    case '(':
    case ')':
    case '{':
    case '}':
    case ' ': printf("\nSEPARATOR: %c found\n", ch);
                                ch =fgetc(fin);
                                break;
    case '_':
    case 'a':
    case 'b':
    ... // The other 24 letters go here
    case 'A':
    case 'B':
    ... // Same thing for uppercase letters
    case 'Z': printf("\nIDENTIFIER: ");
    ...
}

不幸的是,这会导致更长的代码。但是,您可以将其转换为查找表,这样可读性较差,但运行速度大致相同:

enum {
    OTHER
,   ID_START
,   DIGIT
,   SEPARATOR
};

int map_char(unsigned char c) {
    static int *lookup_ptr = NULL;
    static int lookup[256];
    if (lookup_ptr == NULL) {
        for (int i = 0 ; i != 256 ; i++) {
            if (i=='"; || i==';' || i==',' || ...) {
                lookup[i] = SEPARATOR;
            } else if (i=='_' || isalpha(i)) {
                lookup[i] = ID_START;
            } else if (isdigit(i)) {
                lookup[i] = DIGIT;
            } else {
                lookup[i] = OTHER;
            }
        }
        lookup_ptr = lookup;
    }
    return lookup_ptr[c];
}

现在您可以使用以下功能:

switch (map_char(ch)) {
    case SEPARATOR:
        ...
        break;
    case ID_START:
        ...
        break;
    case DIGIT:
        ...
        break;
    case OTHER:
        ...
        break;
}

* scanf函数的方括号语法只看起来像正则表达式,但它不是。

答案 1 :(得分:0)

据我所知,你只能在switch语句中使用硬编码字符串和常量。

所以: 不 - 这不是不可能的

答案 2 :(得分:0)

不,你不能这样做。你正在将正则表达式放在字符文字中,这些字面文字没有意义,或做任何有用的事情(尽管出于晦涩的原因,它实际上并不是非法的)。

由于您只使用字符类,因此纯C替换将是

case '"': case ',': case '(': case ')': ...

(您可以在一个语句中包含任意数量的案例标签)。