从文本文档中提取键+短语的规则
rule to extract key+phrases from a text document
我想从文档中提取关键短语:"something KEY phrase END something ... ect"。我的规则运行良好,但结果不包含键名。获取字符串的规则应该是什么:"KEY phrase"。谢谢指教。
std::vector<std::string> doc;
bool r = qi::phrase_parse(first,last,
( qi::omit[*(qi::char_-"KEY")]
>> qi::lexeme[ "KEY"
>> *(qi::char_-"KEY" -"END")] ) % "END"
, qi::space, doc);
qi::lit(...)
没有合成属性。
qi::string(...)
会。
可能会将 "KEY"
替换为 qi::string("KEY")。 (不知道 doc
的类型很难分辨)
bool r = qi::phrase_parse(first,last,
( qi::omit[*(qi::char_-"KEY")]
>> qi::lexeme[ qi::string("KEY")
>> *(qi::char_-"KEY" -"END")] ) % "END"
, qi::space, doc);
BONUS 另见 seek[]
parser directive 来自 Spirit Repository:
The seek[]
parser-directive skips all input until the subject parser matches.
我会这样做:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/repository/include/qi_seek.hpp>
namespace qi = boost::spirit::qi;
namespace qr = boost::spirit::repository::qi;
extern std::string const sample; // below
int main() {
auto f(sample.begin()), l(sample.end());
std::vector<std::string> phrases;
if (qi::parse(f,l, *qi::as_string[
qr::seek[qi::string("KEY")] >> *(qi::char_ - "END")
], phrases))
{
for (size_t i = 0; i < phrases.size(); ++i)
std::cout << "keyphrase #" << i << ": '" << phrases[i] << "'\n";
}
}
打印:
keyphrase #0: 'KEY@v/0qwJTjgFQwNmose7LiEmAmKpIdK3TPmkCs@'
keyphrase #1: 'KEY@G1TErN1QSSKi17BSnwBKML@'
keyphrase #2: 'KEY@pWhBKmc0sD+o@'
keyphrase #3: 'KEY@pwgjNJ0FvWGRezwi74QdIQdmUuKVyquWuvXz4tBOXqMMqco@'
keyphrase #4: 'KEY@aJ3QUfLh3AqfKyxcUSiDbanZmCNGza6jb6pZ@'
keyphrase #5: 'KEY@bYJzitZUyXlgPA009qBpleHIJ9uJUSdJO78iisUgHkoqUpf+oXZQF9X/7v2fikgemCD@'
此答案的评论中包含示例数据:/此处/
最终基准:
- 灵气(上面sahe的解法)-
项目数:5585 耗时:183.676 秒
- 增强正则表达式 -
项目数:5585 耗时:197.684 秒
- 表达正则表达式 -
项目数:5585 耗时:232.597 秒
数据大小:23.9 MB 文本文件
我想从文档中提取关键短语:"something KEY phrase END something ... ect"。我的规则运行良好,但结果不包含键名。获取字符串的规则应该是什么:"KEY phrase"。谢谢指教。
std::vector<std::string> doc;
bool r = qi::phrase_parse(first,last,
( qi::omit[*(qi::char_-"KEY")]
>> qi::lexeme[ "KEY"
>> *(qi::char_-"KEY" -"END")] ) % "END"
, qi::space, doc);
qi::lit(...)
没有合成属性。
qi::string(...)
会。
可能会将 "KEY"
替换为 qi::string("KEY")。 (不知道 doc
的类型很难分辨)
bool r = qi::phrase_parse(first,last,
( qi::omit[*(qi::char_-"KEY")]
>> qi::lexeme[ qi::string("KEY")
>> *(qi::char_-"KEY" -"END")] ) % "END"
, qi::space, doc);
BONUS 另见 seek[]
parser directive 来自 Spirit Repository:
The
seek[]
parser-directive skips all input until the subject parser matches.
我会这样做:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/repository/include/qi_seek.hpp>
namespace qi = boost::spirit::qi;
namespace qr = boost::spirit::repository::qi;
extern std::string const sample; // below
int main() {
auto f(sample.begin()), l(sample.end());
std::vector<std::string> phrases;
if (qi::parse(f,l, *qi::as_string[
qr::seek[qi::string("KEY")] >> *(qi::char_ - "END")
], phrases))
{
for (size_t i = 0; i < phrases.size(); ++i)
std::cout << "keyphrase #" << i << ": '" << phrases[i] << "'\n";
}
}
打印:
keyphrase #0: 'KEY@v/0qwJTjgFQwNmose7LiEmAmKpIdK3TPmkCs@'
keyphrase #1: 'KEY@G1TErN1QSSKi17BSnwBKML@'
keyphrase #2: 'KEY@pWhBKmc0sD+o@'
keyphrase #3: 'KEY@pwgjNJ0FvWGRezwi74QdIQdmUuKVyquWuvXz4tBOXqMMqco@'
keyphrase #4: 'KEY@aJ3QUfLh3AqfKyxcUSiDbanZmCNGza6jb6pZ@'
keyphrase #5: 'KEY@bYJzitZUyXlgPA009qBpleHIJ9uJUSdJO78iisUgHkoqUpf+oXZQF9X/7v2fikgemCD@'
此答案的评论中包含示例数据:/此处/
最终基准:
- 灵气(上面sahe的解法)- 项目数:5585 耗时:183.676 秒
- 增强正则表达式 - 项目数:5585 耗时:197.684 秒
- 表达正则表达式 - 项目数:5585 耗时:232.597 秒
数据大小:23.9 MB 文本文件