- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
假设我们有一个正则表达式“start:(?: ([0-9]{1,2}))? ([0-9].*)”。
会匹配
std::string string1 = "start: 01 0ab";
和
std::string string2 = "start: 0ab";
我们也可以分别得到2个匹配的字符串。
我尝试使用 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 语法总是贪婪的。
但是,也许您没有找到最优雅的形式,因为您正在寻找“更好”的东西。这就是我要做的。
我会使用船长来匹配空格¹:
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;
Note
qi::graph
doesn't match whitespace, where*qi::char_
simply matches anything at all greedily.
#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::blank
而不是 qi::space
关于c++ - 如何编写 boost::spirit::qi 解析器来执行 '?' 在正则表达式中的作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40043636/
假设我们要解析一个内积表达式并得到结果。 "SUM({1, 2, 3} .* {4, 5, 6})" qi::_1 和 qi::_2 非常方便地在解析器中引用第 i 个属性。 void Test(st
无法弄清楚为什么这条规则 unary_msg 不起作用,它说属性类型是 qi::unused_type 但这对我来说毫无意义。为什么 boost 会这样折磨我? template struct g3:
从测试中我可以得到 qi::uint_parser()与 qi::uint_ 相同.他们从 0 解析整数至 UINT_MAX . 我不明白的是qi::uint_parser需要 std::numeri
bool EqnExprEvaluator::SetEqn(const std::string& eqnStr) { typedef std::string::const_iterator
我一直在使用 Boost 库中的 Spirit Qi 用 C++ 编写语法。作为该语言的新手,很难习惯该库的语法和怪癖,但现在我有点了解它的工作原理。 我在使用 qi::lexeme 时遇到错误。我的
我需要跟踪一些项目在我使用提升灵气解析的文本中的位置。我找到了 this example并适应这样: #include #include #include #include #include
我想做的是在运行时从 ABNF 语法文件创建一个解析器。我已经在 qi::grammar 中实现了所有 ABNF 规则,如下所示: typedef /*qi::rule or struct conta
我在boost_1.59中使用spirit来解析类c语言(名为stone,最初由java编写)。但是我在使用 boost::spirit::qi 解析 c 风格的字符串时遇到了麻烦。整个代码位于 co
我正在用 Boost.Spirit 做一个 IRC 消息解析器,但是当我尝试解析一个输入时我遇到了一个(很长的)错误。我遵循了“Roman Numerals”示例。此外,我将 g++4.7 与 -st
如何解析可能包含 double 或 int 的字符串,具体取决于是否设置了点。例如。 6.0是double类型,6是int类型。规则是 rule,skipper> r = qi::double_|qi
在 boost::spirit::traits::transform_attribute 中指示解析失败的正确方法是什么?我可以抛出任何旧的异常,还是它要我做的特定事情? namespace boos
我正在尝试使用 qi 创建通用解析器元素,因为不幸的是(必须支持 MSVC)无法使用 X3。这个想法是有一个模板化的结构: template struct parse_type; 我可以这样使用: t
我正在尝试创建一个返回 function 的规则通过柯里化(Currying) Phoenix 表达式构造。例如, start = int_[_val = xxx]; rule start; 应该做什
我正在解析一个文本文件,可能有几 GB 的大小,由以下几行组成: 11 0.1 14 0.78 532 -3.5 基本上,每行一个整数和一个 float 。整数应该是有序的并且是非负的。我想验证数据是
我想提出一个让我陷入困境的主题,并提出了一个关于齐::符号。 这一切都始于我查看新的野兽图书馆并阅读 atutorial example 它以一个从 http 路径猜测 mime 类型的函数开始扩展。
我有一段 boost::spirit::qi 代码可以匹配 "M7.x.y.z" 或 "M7.x.y.z ",但我想要一个在前一个输入上失败的解析器。 我想我需要在其中插入 qi::lexeme[]
我正在尝试为一种语言的多个子集定义一些 Boost::spirit::qi 解析器,代码重复最少。为此,我创建了一些基本的规则构建函数。原来的解析器工作正常,但一旦我开始使用组合函数,我的解析器似乎就
假设我有一个简单的类型foo: struct foo { void bar(int) { // do something } }; 我想使用 Boost.Qi 来解析字符串中的整数字段,并使用结果值调
(免责声明,我正在学习提升精神) 我正在尝试解析这样的表达式:F( 1 ) 并希望将 1 作为字符串(“1”而不是数字(与 qi::int_ 一起使用))。 我试过这样的事情(这是错误的,但也许我的方
假设我有两个用逗号分隔的 double 来解析返回它们的总和。在 Haskell 中我可能会这样做: import Data.Attoparsec.Text import Data.Text (pac
我是一名优秀的程序员,十分优秀!