簡體   English   中英

使用提升精神從括號中提取字符串

[英]extracting string from bracket using boost spirit

我有以下字符串:

%%DocumentNeededResources: CMap (90pv-RKSJ-UCS2C)

我想解析它並存儲/提取90pv-RKSJ-UCS2C字符串。

我的規則如下:

std::string strLinesRecur = "%%DocumentNeededResources: CMap (90pv-RKSJ-UCS2C)";
std::string strStartTokenRecur;
std::string token_intRecur;
bool bParsedLine1 = qi::phrase_parse(strLinesRecur.begin(), strLinesRecur.end(), +char_>>+char_,':', token_intRecur, strStartTokenRecur);

看起來你認為船長是拆分分隔符。 這恰恰相反( Boost精神船長問題 )。

在這種罕見的情況下,我想我更喜歡正則表達式。 但是,既然你問這里的精神:

住在Coliru

#include <boost/spirit/include/qi.hpp>

namespace qi = boost::spirit::qi;

int main() {
    std::string const line = "%%DocumentNeededResources: CMap (90pv-RKSJ-UCS2C)";

    auto first = line.begin(), last = line.end();

    std::string label, token;
    bool ok = qi::phrase_parse(
            first, last, 
            qi::lexeme [ "%%" >> +~qi::char_(":") ] >> ':' >> qi::lexeme["CMap"] >> '(' >> qi::lexeme[+~qi::char_(')')] >> ')',
            qi::space,
            label, token);

    if (ok)
        std::cout << "Parse success: label='" << label << "', token='" << token << "'\n";
    else
        std::cout << "Parse failed\n";

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

打印

Parse success: label='DocumentNeededResources', token='90pv-RKSJ-UCS2C'

好吧,假設我們給出了以下using和別名命名空間指令:

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

並給出字符串:

std::string strLinesRecur = "%%DocumentNeededResources: CMap (90pv-RKSJ-UCS2C)";

我們想將括號內的“代碼”提取到res

std::string res;

一種方法是使用boost::phoenix::ref作為語義動作。 所以給出一個代碼語法:

using boost::spirit::ascii::alnum;
auto code = copy(+(alnum | char_('-')));

(這與正則表達式中的內容一致[a-zA-Z\\-]

我們可以為整個字符串創建自己的語法:

using boost::spirit::ascii::alpha;
auto grammar = copy(
    (char_('%') >> char_('%') >> +alpha >> char_(':')) 
        >> +alpha >> char_('(') >> as_string[lexeme[code]][phx::ref(res) = _1] >> char_(')'));

其分析任何兩個開頭% ,具有一定的字母和一個如下: ,然后用括號內的一些“代碼”如下。

這一點的全部內容是as_string[lexeme[code]][phx::ref(res) = _1] 如果我們將其分解: lexeme[code]只是將解析后的code視為原子單元, as_string將結果返回為std::string (而不是std::vector<char> )和[phx::ref(res) = _1]使用語義動作將解析后的字符串存儲到res_1是該語法中第一個匹配的占位符)。

在這種情況下,以下調用將跳過空格:

using boost::spirit::ascii::blank;
phrase_parse(begin(strLinesRecur), end(strLinesRecur), grammar, blank);

現場演示

這當然只是適合字符串的語法示例。

注意: copy指的是qi::copy ,它是一種能夠存儲對象codegrammar片段的方法。 沒有它, auto的使用將失敗(可能有分段錯誤)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM