我正在编写一个语法,其中包含解析电子邮件地址的规则。 规则声明为:
qi::rule<Iterator, ascii::space_type, std::string()> email;
,其定义是:
email
=
qi::lexeme[
+ascii::alnum
>> *(qi::char_(".") >> +ascii::alnum)
>> qi::char_("@")
>> +ascii::alnum
>> +(qi::char_(".") >> +ascii::alnum)
]
当我使用此语法解析文本时,解析器正确匹配电子邮件地址,但规则的合成属性与正确的地址不对应。例如,如果文本包含地址info.it@example.com,则合成属性为info。@ example。我认为这是由于kleen和plus运营商。
我正在使用boost 1.48并且我已经使用boost 1.54测试了代码,并且在该版本中它运行正常,但遗憾的是我无法在我的项目中升级到它。
我可以解决这个问题,也许使用语义动作?
答案 0 :(得分:1)
有趣。
我认为它与容器属性如何通过后续容器处理解析器表达式附加到的更改有关。
我不会安装该库版本,但您可以执行以下操作:
注意
您的模式不适用于一般电子邮件地址。 实际上,这很“复杂”更复杂。我假设您的规则适合您的内部要求。
你的规则在任何地方都不允许
..
,对吗?假设这也是故意的您的规则也不会在子字符串的开头或结尾处开始
.
。假设这也是故意的
放弃船长,因为整个规则是一个词汇:(见Boost spirit skipper issues)
qi::rule<Iterator, std::string()> email;
email =
+ascii::alnum
>> *(qi::char_(".") >> +ascii::alnum)
>> qi::char_("@")
>> +ascii::alnum
>> +(qi::char_(".") >> +ascii::alnum)
;
现在,使用raw[]
或as_string[]
收集整个输入:
qi::rule<Iterator, std::string()> email;
email = qi::as_string [
+ascii::alnum
>> *(qi::char_(".") >> +ascii::alnum)
>> qi::char_("@")
>> +ascii::alnum
>> +(qi::char_(".") >> +ascii::alnum)
];
使用raw[]
您甚至不需要捕获属性,从而使规则更加高效和简单:
qi::rule<Iterator, std::string()> email;
email = qi::raw [
+ascii::alnum >> *('.' >> +ascii::alnum)
>> '@'
>> +ascii::alnum >> +('.' >> +ascii::alnum)
];