2009-02-18 9 views
2

Я хочу проанализировать строки, чтобы проверить, указан ли они синтаксис или нет.Как выполнить синтаксический анализ строки в C++

Пример:

Str = Z344-R565l t 

Вот мое требование после того, как Z должна быть числом, и после этого - и после этого R должны быть там с последующим числом, за которым следует l, за которым следует пробел и затем, наконец, t.

Если что-либо другое, кроме этого, должно быть ошибкой.

Мне нужно разобрать много разных синтаксисов, подобных этому. Мне было бы неудобно писать функцию для каждого типа синтаксиса. Я слышал, что yacc или lex могут решить эту проблему.

Может ли кто-нибудь пролить свет на мою проблему?

ответ

4

Использование подталкивание :: регулярное выражение

#include <string> 
#include <boost/regex.hpp> 

bool isMatch(std::string input){ 
    boost::regex r("Z[0-9]*-R[0-9]*l t"); 
    return boost::regex_search(input, r); 
} 

Другое дело, что вы могли бы сделать, это предоставить список регулярных выражений выражений в файле, одно выражение в каждой строке. Создайте вектор объектов boost :: regex, используя ввод файла и проведите по вектору шаблонов для каждой строки, которую нужно проверить. Это не очень эффективно, но это сработает.

1

Вы можете Google «runtime parser generation» или что-то подобное ...

lex и yacc (или их GNU equivaents flex и bison) делают свою работу во время компиляции и не может быть достаточно гибким для ваших нужд. (или они могут, вы не очень специфичны).

+0

Лекса и Yacc является излишеством для того, что вы хотите сделать. Они хороши, если вы хотите создать небольшой язык программирования. – zooropa

6

Вы делаете это с помощью регулярного выражения.

Z344-R565l т

Ваше регулярное выражение должно выглядеть следующим образом. Не уверен, что библиотека регулярных выражений для C++, но это общее регулярное выражение, чтобы убедиться, что ваша строка соответствует.

Z[0-9]+-R[0-9]+l t 
+1

Если все его дела настолько легкие, он действительно может уйти с регулярными выражениями. Но я всегда отказываюсь от рекомендаций, потому что люди так часто пытаются применить их там, где они не принадлежат. – dmckee

+1

Согласен, я думаю, что идея о том, что «я могу использовать регулярное выражение», чрезмерно используется. Однако в подобных случаях я думаю, что это будет работать неплохо. – Suroot

4

Boost :: Regex отлично, если вы просто хотите проверить синтаксис. Если вы хотите сделать что-то, когда вы читаете такое выражение, я предлагаю вам использовать повышение :: дух что-то вроде:

rule<> testFormula = 
    (ch_p('Z') >> int_p) 
    >> (ch_p('-')>>ch_p('R')>>int_p>>ch_p('l')) 
    >> space_p >> ch_p('t'); 

Я изолированные частей выражения, которые вы можете подключить к некоторому действию (используя оператор []).

Смотрите documentation для получения дополнительной информации

1

Если у вас есть недавний компилятор (VC 2008 SP1 и т.д.), нет необходимости использовать импульс, регулярного выражения является часть TR1, и вы можете использовать их с этим заголовком: #include <regex>

Пример для даты (you should use double \ as escape character):

string dateorder = "12/07/2009"; 

tr1::regex expr("^([1-2][0-9]|0?[1-9]|30|31)/([1-9]|10|11|12)/(2\\\d{3})$"); 

if (!regex_match(dateorder.begin(),dateorder.end(),expr)) 
{ 
    ... 
    break; 
} 
Смежные вопросы