Вопрос

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

Пример:

Str = Z344-R565l t

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

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

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

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

Это было полезно?

Решение

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

#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, используя входные данные файла, и выполните итерацию по вектору шаблонов для каждой строки, которую вам нужно проверить.Это не очень эффективно, но это сработает.

Другие советы

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

Z344-R565l т

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

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

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

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

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

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

Вы могли бы погуглить "runtime parser generation" или что-то подобное...

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

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

Пример для даты (вы должны использовать double \ как экранирующий символ):

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;  
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top