使用 spirit 解析器从字符串中提取值
Extracting Values from string using spirit parser
我有以下一行
/90pv-RKSJ-UCS2C usecmap
std::string const line = "/90pv-RKSJ-UCS2C usecmap";
auto first = line.begin(), last = line.end();
std::string label, token;
bool ok = qi::phrase_parse(
first, last,
qi::lexeme [ "/" >> +~qi::char_(" ") ] >> ' ' >> 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";
我想在标签中使用90pv-RKSJ-UCS2C,在令牌变量中使用usecmap。
我提取了 90pv-RKSJ-UCS2C 值但没有使用 cmap
使用 space
船长,您永远无法匹配 ' '
(它被跳过了!)。另见:Boost spirit skipper issues
所以,要么不使用船长,要么让船长吃掉它:
bool ok = qi::phrase_parse(
first, last,
qi::lexeme [ "/" >> +qi::graph ] >> qi::lexeme[+qi::graph], qi::blank, label, token);
备注:
- 我使用
qi::graph
而不是 ~qi::char_(" ")
公式
我用了blank_type
因为你说
i have following line
这意味着不应跳过行尾
演示
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
int main()
{
std::string const line = "/90pv-rksj-ucs2c usecmap";
auto first = line.begin(), last = line.end();
std::string label, token;
bool ok = qi::phrase_parse(
first, last,
qi::lexeme [ "/" >> +qi::graph ] >> qi::lexeme[+qi::graph], qi::blank, 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='90pv-rksj-ucs2c', token='usecmap'
如果你使用的是 C++11,我建议使用正则表达式。
#include <iostream>
#include <regex>
using namespace std;
int main() {
regex re("^/([^\s]*)\s([^\s]*)"); // 1st () captures
// 90pv-RKSJ-UCS2C and 2nd () captures usecmap
smatch sm;
string s="/90pv-RKSJ-UCS2C usecmap";
regex_match(s,sm,re);
for(int i=0;i<sm.size();i++) {
cout<<sm[i]<<endl;
}
string label=sm[1],token=sm[2];
system("pause");
}
我有以下一行 /90pv-RKSJ-UCS2C usecmap
std::string const line = "/90pv-RKSJ-UCS2C usecmap";
auto first = line.begin(), last = line.end();
std::string label, token;
bool ok = qi::phrase_parse(
first, last,
qi::lexeme [ "/" >> +~qi::char_(" ") ] >> ' ' >> 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";
我想在标签中使用90pv-RKSJ-UCS2C,在令牌变量中使用usecmap。
我提取了 90pv-RKSJ-UCS2C 值但没有使用 cmap
使用 space
船长,您永远无法匹配 ' '
(它被跳过了!)。另见:Boost spirit skipper issues
所以,要么不使用船长,要么让船长吃掉它:
bool ok = qi::phrase_parse(
first, last,
qi::lexeme [ "/" >> +qi::graph ] >> qi::lexeme[+qi::graph], qi::blank, label, token);
备注:
- 我使用
qi::graph
而不是~qi::char_(" ")
公式 我用了
blank_type
因为你说i have following line
这意味着不应跳过行尾
演示
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
int main()
{
std::string const line = "/90pv-rksj-ucs2c usecmap";
auto first = line.begin(), last = line.end();
std::string label, token;
bool ok = qi::phrase_parse(
first, last,
qi::lexeme [ "/" >> +qi::graph ] >> qi::lexeme[+qi::graph], qi::blank, 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='90pv-rksj-ucs2c', token='usecmap'
如果你使用的是 C++11,我建议使用正则表达式。
#include <iostream>
#include <regex>
using namespace std;
int main() {
regex re("^/([^\s]*)\s([^\s]*)"); // 1st () captures
// 90pv-RKSJ-UCS2C and 2nd () captures usecmap
smatch sm;
string s="/90pv-RKSJ-UCS2C usecmap";
regex_match(s,sm,re);
for(int i=0;i<sm.size();i++) {
cout<<sm[i]<<endl;
}
string label=sm[1],token=sm[2];
system("pause");
}