2013-11-02 5 views
0

Я делаю свой miniSQL и пытаюсь использовать регулярное выражение для анализа пользовательского ввода.Резервные пустые строки после regex_match()

Мне не удалось обработать случай «create table myTable (c char (20))». Как показано ниже, вторая и третья линии нежелательны. Мне просто интересно, почему они появятся в результате.

Вот мой код:

void onCreateTable(const smatch& cmd); 

int main() 
{ 
    std::string cmd = " create table a(c char(20))"; 
    regex pattern; 
    smatch result; 
    pattern = regex("\\s*create\\s+table\\s+(\\w+)\\s*\\((.*)\\)\\s*", regex::icase); 
    if (regex_match(cmd, result, pattern)) 
    { 
     onCreateTable(result); 
    } 

    int x; cin >> x; 
    return 0; 
} 

void onCreateTable(const smatch& cmd) 
{ 
    cout << "onCreateTable" << endl; 
    string tableName = cmd[1]; 
    string attr = cmd[2]; 
    regex pattern = regex("\\s*(\\w+\\s+int)|(\\w+\\s+float)|(\\w+\\s+char\\(\\d+\\))",  regex::icase); 
    // which will print redundant blank lines 

    // while the below one will print the exact result 
    // regex pattern = regex("\\s*(\\w+\\s+char\\(\\d+\\))", regex::icase); 
    smatch result; 
    if (regex_match(attr, result, pattern)) 
    { 
     cout << "match!" << endl; 
     for (size_t i = 0; i < result.size(); i ++) 
     { 
      cout << result[i] << endl; 
     } 
    } else 
    { 
     cout << "A table must have at least 1 column." << endl; 
    } 
} 
+0

Похоже, что он записывает группу для всех трех выражений в скобках, но, очевидно, только один из них на самом деле соответствует, поэтому он печатает первые два в виде пробелов. Что произойдет, если вы завершите все выражение после '\\ s *' в дополнительной паре круглых скобок? Если вы измените порядок, чтобы группа с символом 'char' в нем находилась перед двумя другими, вы получаете две пустые строки в конце, а не в середине? –

ответ

0

Ваш последний Regex имеет 3 захвата групп, разделенных чередованием.
Только 1 будет соответствовать. Вы сидите в петле, печатая весь массив smatch.
Массив smatch - это размер всех ваших групп захвата.

 \s* 
1 (\w+ \s+ int) 
    | 
2 (\w+ \s+ float) 
    | 
3 (\w+ \s+ char\(\d+ \)) 

Группа 0 - это все совпадение.
Группа 1 не соответствует, ее пустая.
Группа 2 не соответствует, ее пустая.
Группа 3 matchd.

Возможно, вам захочется проверить, соответствует ли группа.
Что-то вроде if (result[i].matched) {}
Или любой другой способ использования флагов.

+0

Я вижу. Спасибо! –

Смежные вопросы