首页 文章

路径验证的精神语法

提问于
浏览
1

我正在尝试使用boost spirit来编写一个简单的语法来验证字符串是否是有效的目录 . 我正在使用这些教程,因为这是我尝试过的第一个语法:http://www.boost.org/doc/libs/1_36_0/libs/spirit/doc/html/spirit/qi_and_karma.html http://www.boost.org/doc/libs/1_48_0/libs/spirit/doc/html/spirit/qi/reference/directive/lexeme.html http://www.boost.org/doc/libs/1_44_0/libs/spirit/doc/html/spirit/qi/tutorials/employee___parsing_into_structs.html

目前,我想出的是:

// I want these to be valid matches
std::string valid1 = "./";
// This string could be any number of sub dirs i.e. /home/user/test/ is valid
std::string valid2 = "/home/user/";

using namespace boost::spirit::qi;
bool match = phrase_parse(valid1.begin(), valid1.end(), lexeme[
    ((char_('.') | char_('/')) >> +char_ >> char_('/')],
    ascii::space);
if (match)
{
    std::cout << "Match!" << std::endl;
}

但是,这没什么好看的 . 我有一些关于为什么的想法;然而,经过一些研究后,我还没有找到答案 . 例如,我假设char_可能会消耗所有字符?那么如何判断一些字符序列是否以/结尾?

基本上我在写上面代码背后的想法是我希望目录开头 . 和/有效,然后最后一个字符必须是/ . 有人可以用我的语法帮助我,还是指点一些类似于我想做的事情?这纯粹是学习如何使用精神的一种消解 .

Edit 所以我使用的解析器匹配:

bool match = phrase_parse(valid1.begin(), valid1.end(), lexeme[
    ((char_('.') | char_('/')) >> *(+char_ >> char_('/'))],
    ascii::space);
if (match)
{
    std::cout << "Match!" << std::endl;
}

不确定这是否合适?或者如果由于其他原因匹配...也应该在这里使用ascii :: space吗?我在教程中读到它是为了使空间不可知,即b等同于ab . 在路径名中我不想要哪个?如果使用不正确的东西会是什么?

SSCCE:

#include <string>
#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_char.hpp>
#include <boost/spirit/include/qi_eoi.hpp>

int main()
{
  namespace qi = boost::spirit::qi;
  std::string valid1 = "./";
  std::string valid2 = "/home/blah/";
  bool match = qi::parse(valid2.begin(), valid2.end(), &((qi::lit("./")|'/') >> (+~qi::char_('/') % '/') >> qi::eoi));

  if (match)
  {
    std::cout << "Match" << std::endl;
  }
}

1 回答

  • 2

    如果你没有't want to ignore space differences (which you shouldn' t),请使用 parse 而不是 phrase_parse . lexeme 的使用再次禁止了船长(所以你只是剥离了前导/尾随空间) . 另见stackoverflow.com/questions/17072987/boost-spirit-skipper-issues/17073965#17073965

    使用 char_("ab") 而不是 char_('a')|char_('b') .

    *char_ 匹配 everything . 你可能意味着 *~char_('/') .

    我建议像

    bool ok = qi::parse(b, f, &(lit("./")|'/') >> (*~char_('/') % '/'));
    

    这不会暴露匹配的输入 . 在它周围添加 raw[] 来实现这一目标 .

    添加 > qi::eoi 以断言所有输入都已消耗 .

相关问题