gpt4 book ai didi

c++ - 使用前导和尾随空格 boost spirit 解析字符串

转载 作者:搜寻专家 更新时间:2023-10-31 01:43:37 24 4
gpt4 key购买 nike

我对 Boost spirit 还是个新手。

我正在尝试解析一个可能包含前导和尾随空格以及中间空格的字符串。我想对字符串执行以下操作

  1. 删除所有尾随和前导空格
  2. 将单词之间的空格限制为一个空格

例如

"(  my   test1  ) (my  test2)"

被解析为两个术语 -

"my test1" 
"my test2"

我使用了以下逻辑

using boost::spirit::qi;
struct Parser : grammar<Iterator, attribType(), space_type>
{
public:
Parser() : Parser::base_type(term)
{
group %= '(' >> (group | names) >> ')';
names %= no_skip[alnum][_val=_1];
}

private:
typedef boost::spirit::qi::rule<Iterator, attribType(), space_type> Rule;
Rule group;
Rule names
}

虽然它允许保留中间的空间。不幸的是,它还会保留标题和尾随空格以及多个中间空格。我想为此找到更好的逻辑。

我确实在网上看到了使用带有 boost::spirit::qi::skip 的自定义 skipper 的引用资料,但我还没有找到一个有用的空格示例。还有其他人有这方面的经验吗?

最佳答案

我建议在解析之后(而不是在解析期间)进行修整/规范化。

也就是说,你可以像这样破解它:

name   %= lexeme [ +alnum ];
names %= +(name >> (&lit(')') | attr(' ')));
group %= '(' >> (group | names) >> ')';

查看 Live On Coliru

输出:

Parse success
Term: 'my test1'
Term: 'my test2'

我引入 name 规则只是为了 boost 可读性。请注意 (&lit(')') | attr(' ')) 是一种奇特的说法:

If the next character matches ')' do nothing, otherwise, append ' ' to the synthesized attribute

完整代码:

#define BOOST_SPIRIT_DEBUG
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;

using Iterator = std::string::const_iterator;

using attribType = std::string;

struct Parser : qi::grammar<Iterator, attribType(), qi::space_type>
{
public:
Parser() : Parser::base_type(group)
{
using namespace qi;

name %= lexeme [ +alnum ];
names %= +(name >> (&lit(')') | eps [ phx::push_back(_val, ' ') ]));
group %= '(' >> (group | names) >> ')';

BOOST_SPIRIT_DEBUG_NODES((name)(names)(group))
}

private:
typedef boost::spirit::qi::rule<Iterator, attribType(), qi::space_type> Rule;
Rule group, names, name;
};


int main()
{
std::string const input = "( my test1 ) (my test2)";

auto f(input.begin()), l(input.end());

Parser p;

std::vector<attribType> data;
bool ok = qi::phrase_parse(f, l, *p, qi::space, data);

if (ok)
{
std::cout << "Parse success\n";
for(auto const& term : data)
std::cout << "Term: '" << term << "'\n";
}
else
{
std::cout << "Parse failed\n";
}

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

关于c++ - 使用前导和尾随空格 boost spirit 解析字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24867600/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com