Как разобрать строку в C ++
-
05-09-2019 - |
Вопрос
Я хочу разобрать строки, чтобы проверить, задан ли в них синтаксис или нет.
Пример:
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;
}