你考虑过灵性吗?当然,您没有指定如何在上下文中检测后缀(您是否需要在末尾添加它们,您是否需要在其前面添加一些语法等),但是您可以执行以下操作:
x3::symbols<Char> sym;
sym += "foo", "bar", "qux";
它构建了一个 Trie,非常有效。它可以解析任何类型的输入迭代器(如果您愿意的话,包括流)。只需添加一些针对上下文要求的魔法约束,例如输入结束:
bool has_suffix(string_view sv) {
return parse(sv.cbegin(), sv.cend(), x3::seek[suffix >> x3::eoi]);
}
如果您甚至希望返回字符串的文本值,只需执行以下操作:
string_view get_suffix(string_view sv) {
boost::iterator_range<string_view::const_iterator> output;
parse(sv.cbegin(), sv.cend(), x3::seek[x3::raw[suffix >> x3::eoi]], output);
return {output.begin(), output.size()};
}
Spirit 为您提供了很大的自由来围绕智能,动态添加/删除符号,例如使用no_case
与 Trie 等
完整演示
使用 X3 (c++14)
Live On Coliru
#include <boost/spirit/home/x3.hpp>
#include <string_view>
#include <cstdint>
namespace Demo {
using Char = char32_t;
using string_view = std::basic_string_view<Char>;
namespace x3 = boost::spirit::x3;
static auto const suffix = [] {
x3::symbols<Char> sym;
sym += "foo", "bar", "qux";
return sym; // x3::no_case[sym];
}();
bool has_suffix(string_view sv) {
return parse(sv.cbegin(), sv.cend(), x3::seek[suffix >> x3::eoi]);
}
string_view get_suffix(string_view sv) {
boost::iterator_range<string_view::const_iterator> output;
parse(sv.cbegin(), sv.cend(), x3::seek[x3::raw[suffix >> x3::eoi]], output);
return {output.begin(), output.size()};
}
}
#include <iostream>
#include <iomanip>
int main() {
using namespace Demo;
auto widen = [](string_view sv) { return std::wstring(sv.begin(), sv.end()); };
std::wcout << std::boolalpha;
for (string_view testcase : { U"nope", U"lolbar you betqux" }) {
std::wcout
<< widen(testcase)
<< L" -> " << has_suffix(testcase)
<< L" (" << widen(get_suffix(testcase))
<< L")\n";
}
}
Prints
nope -> false ()
lolbar you betqux -> true (qux)
灵气版
A literal port: Live On Coliru
A C++11 only version: Live On Coliru
And a C++03 version for the really retro programming experience: Live On Coliru