如何编写一个 boost::spirit::qi 解析器来做'?'在正则表达式中做的事情?
How to write a boost::spirit::qi parser to do what '?' does in regex?
假设我们有一个正则表达式"start:(?([0 - 9] {1,2})) ?([0 - 9] *)"。
它将匹配
std::string string1 = "start: 01 0ab";
和
std::string string2 = "start: 0ab";
也可以分别得到两个匹配的字符串。
我尝试使用boost::spirit::qi解析器来解析string2,但是无法匹配。
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,但是有一个更通用的方法来实现正则表达式操作符'?"?谢谢!
我不确定期望有什么问题。这是处理歧义规则的唯一方法,因为PEG语法总是贪婪的。
然而,也许你没有得到最优雅的形式,因为你在寻找"更好"的东西。这是我要做的。
我将使用一个skipper来匹配空格¹:
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
不匹配空格,*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 << "matchn";
else
std::cout << "not matchn";
if (it_begin!=it_end)
std::cout<<"Remaining unparsed input: '" << std::string(it_begin, it_end) << "'n";
}
}
打印
match
match
¹这假设多个/不同的空白是可以的。如果换行符不应算作空白,则使用qi::blank
代替qi::space
相关文章:
- 使用正则表达式regex_search在字符串中查找字符串
- 在 C++ 中使用正则表达式错误时出现问题 括号表达式中的范围无效
- C++正则表达式无限循环
- FindPackageHandleStandardArgs.cmake:137 的 CMake 错误(消息):找不到 Boost (缺少:正则表达式)(找到合适的版本"1.72.0",
- 定义有趣的宏和正则表达式在Z3 C++绑定
- 带有多个字符分隔符的正则表达式
- C++ 使用增强正则表达式库时断言崩溃
- 有人可以帮助我处理正则表达式吗?
- 用C++编写正则表达式的正确方法是什么?
- 如何编写将验证以下字符串的正则表达式?
- 编写正则表达式模式 c++
- 如何编写正则表达式以匹配以下数字格式?
- 如何为字符串编写正则表达式,其中包含一个数字至少一个数字,并且不包含任何字母
- 在编写gawk代码时区分除法和正则表达式
- 如何用c++编写正则表达式
- 如何在Flex中编写以下正则表达式
- 编写c++正则表达式以匹配#include预处理指令
- 如何编写一个 boost::spirit::qi 解析器来做'?'在正则表达式中做的事情?
- 我想用正则表达式处理字符串,但如何编写正确的正则表达式
- 如何编写一个正则表达式来匹配((113)(96 15)(23))