2016-10-14 5 views
2

정규식이 "start :(?: ([0-9] {1,2})? ([0-9]. *)"라고 가정 해 봅시다.boost :: spirit :: qi 파서를 작성하는 방법 '을 수행 하시겠습니까?' 정규식에서 무엇입니까?

std::string string1 = "start: 01 0ab"; 

std::string string2 = "start: 0ab"; 

우리는 또한 각각이 일치하는 문자열을 얻을 수 있습니다 일치합니다.

string2를 구문 분석하기 위해 boost :: spirit :: qi 구문 분석기를 사용하려고했지만 일치하지 않습니다.

qi::rule<std::string::const_iterator, std::string()> rule1 = qi::repeat(1,2)[qi::digit]; 
qi::rule<std::string::const_iterator, std::string()> rule2 = qi::digit >> *qi::char_; 
std::vector<std::string> attr; 
auto it_begin = string2.begin(); 
auto it_end = string2.end(); 
if (qi::parse(
    it_begin, 
    it_end, 
    qi::lit("start:") 
     >> -(qi::lit(" ") >> rule1) 
     >> qi::lit(" ") >> rule2 
     >> qi::eoi, 
    attr)) 
    std::cout<<"match"<<std::endl; 
else 
    std::cout<<"not match"<<std::endl; 

우리는 물론 규칙 1의 의미를 확인하는 모습 미리 연산자를 사용할 수 있지만 정규식 연산자를 구현하는 더 일반적인 접근 방식이 '?' ? 감사!

답변

3

나는 무엇이 잘못되었는지 확신하지 못한다. PEG 문법은 항상 욕심이 많기 때문에 다른 방법으로 모호한 규칙을 적용하는 유일한 방법입니다.

그러나 당신이 뭔가 "더 나은"것을 찾고 있었기 때문에 당신이 가장 우아한 형태로 도착하지 않았을 수도 있습니다. 여기 내가하는 일이있다.

(선장없이이 선언 되었기 때문에) 규칙이 여전히 어휘이다
if (qi::phrase_parse(it_begin, it_end, 
       "start:" >> -rule1 >> rule2 >> qi::eoi, 
       qi::space, attr)) 

:

qi::rule<It, std::string()> const 
    rule1 = qi::digit >> qi::digit >> &qi::space, 
    rule2 = qi::digit >> *qi::graph; 

qi::graph 아무튼 '

나는 spaces¹에 맞게 선장을 사용하십시오 t는 공백과 일치합니다. *qi::char_과 완전히 일치합니다.은 탐욕 스럽습니다.

Live On Coliru

#include <boost/spirit/include/qi.hpp> 
namespace qi = boost::spirit::qi; 

int main() { 
    using It = std::string::const_iterator; 

    // implicitly lexemes (no skipper in rule declaration) 
    qi::rule<It, std::string()> const 
     rule1 = qi::digit >> qi::digit >> &qi::space, 
     rule2 = qi::digit >> *qi::graph; 

    for (std::string const input : { "start: 01 0ab", "start: 0ab", }) { 
     std::vector<std::string> attr; 

     auto it_begin = input.begin(); 
     auto it_end = input.end(); 

     if (qi::phrase_parse(it_begin, it_end, "start:" >> -rule1 >> rule2 >> qi::eoi, qi::space, attr)) 
      std::cout << "match\n"; 
     else 
      std::cout << "not match\n"; 

     if (it_begin!=it_end) 
      std::cout<<"Remaining unparsed input: '" << std::string(it_begin, it_end) << "'\n"; 
    } 
} 

인쇄
match 
match 

이 여러/다른 공백이 괜찮 가정 ¹. 개행 문자가 공백으로 계산되지 않으면 qi::space

대신 qi::blank을 사용하십시오.