用boost精神解析html转义序列
Parse html escape sequence with boost spirit
我尝试用 html 转义序列解析文本,并想用 utf8 等价物来改变这个转义:
- 0xC2A0 utf8 representation
­ - 0xC2AD utf8 representation
并且有语法来解决这个问题
template <typename Iterator>
struct HTMLEscape_grammar : qi::grammar<Iterator, std::string()>
{
HTMLEscape_grammar() :
HTMLEscape_grammar::base_type(text)
{
htmlescapes.add(" ", 0xC2AD);
htmlescapes.add("­", 0xC2AD);
text = +((+(qi::char_ - htmlescapes)) | htmlescapes);
}
private:
qi::symbols<char, uint32_t> htmlescapes;
qi::rule<Iterator, std::string()> text;
};
但是当我们解析
std::string l_test = "test­as test simple­test";
HTMLEscape_grammar<std::string::const_iterator> l_gramar;
std::string l_ast;
bool result = qi::parse(l_test.begin(), l_test.end(), l_gramar, l_ast);
我们没有得到utf-8字符串,utf8符号的0xC2部分简单的切掉了,我们得到的只是ascii字符串。此解析器是更强大系统的构建块,因此需要 utf8 输出。
我不知道您如何认为公开 uint32_t 会神奇地输出 UNICODE 代码点。更不用说某些东西会为此神奇地执行 UTF8 编码了。
现在让我说清楚。您希望将选择的 HTML 实体引用 替换为 슭(HANGUL SYLLABLE SEULG)。在 UTF-8 中是 0xEC 0x8A 0xAD。
只需自己进行编码(无论如何,您正在编写一个 UTF8 代码单元的输出流):
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <iomanip>
namespace qi = boost::spirit::qi;
template <typename Iterator>
struct HTMLEscape_grammar : qi::grammar<Iterator, std::string()>
{
HTMLEscape_grammar() :
HTMLEscape_grammar::base_type(text)
{
htmlescapes.add(" ", { '\xEC', '\x8A', '\xAD' });
htmlescapes.add("­", { '\xEC', '\x8A', '\xAD' });
text = *(htmlescapes | qi::char_);
}
private:
qi::symbols<char, std::vector<char> > htmlescapes;
qi::rule<Iterator, std::string()> text;
};
int main() {
std::string const l_test = "test­as test simple­test";
HTMLEscape_grammar<std::string::const_iterator> l_gramar;
std::string l_ast;
bool result = qi::parse(l_test.begin(), l_test.end(), l_gramar, l_ast);
if (result) {
std::cout << "Parse success\n";
for (unsigned char ch : l_ast)
std::cout << std::setw(2) << std::setfill('0') << std::hex << std::showbase << static_cast<int>(ch) << " ";
} else
{
std::cout << "Parse failure\n";
}
}
版画
Parse success
0x74 0x65 0x73 0x74 0xec 0x8a 0xad 0x61 0x73 0x20 0x74 0x65 0x73 0x74 0x20 0x73 0x69 0x6d 0x70 0x6c 0x65 0xec 0x8a 0xad 0x74 0x65 0x73 0x74
我尝试用 html 转义序列解析文本,并想用 utf8 等价物来改变这个转义:
- 0xC2A0 utf8 representation
­ - 0xC2AD utf8 representation
并且有语法来解决这个问题
template <typename Iterator>
struct HTMLEscape_grammar : qi::grammar<Iterator, std::string()>
{
HTMLEscape_grammar() :
HTMLEscape_grammar::base_type(text)
{
htmlescapes.add(" ", 0xC2AD);
htmlescapes.add("­", 0xC2AD);
text = +((+(qi::char_ - htmlescapes)) | htmlescapes);
}
private:
qi::symbols<char, uint32_t> htmlescapes;
qi::rule<Iterator, std::string()> text;
};
但是当我们解析
std::string l_test = "test­as test simple­test";
HTMLEscape_grammar<std::string::const_iterator> l_gramar;
std::string l_ast;
bool result = qi::parse(l_test.begin(), l_test.end(), l_gramar, l_ast);
我们没有得到utf-8字符串,utf8符号的0xC2部分简单的切掉了,我们得到的只是ascii字符串。此解析器是更强大系统的构建块,因此需要 utf8 输出。
我不知道您如何认为公开 uint32_t 会神奇地输出 UNICODE 代码点。更不用说某些东西会为此神奇地执行 UTF8 编码了。
现在让我说清楚。您希望将选择的 HTML 实体引用 替换为 슭(HANGUL SYLLABLE SEULG)。在 UTF-8 中是 0xEC 0x8A 0xAD。
只需自己进行编码(无论如何,您正在编写一个 UTF8 代码单元的输出流):
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <iomanip>
namespace qi = boost::spirit::qi;
template <typename Iterator>
struct HTMLEscape_grammar : qi::grammar<Iterator, std::string()>
{
HTMLEscape_grammar() :
HTMLEscape_grammar::base_type(text)
{
htmlescapes.add(" ", { '\xEC', '\x8A', '\xAD' });
htmlescapes.add("­", { '\xEC', '\x8A', '\xAD' });
text = *(htmlescapes | qi::char_);
}
private:
qi::symbols<char, std::vector<char> > htmlescapes;
qi::rule<Iterator, std::string()> text;
};
int main() {
std::string const l_test = "test­as test simple­test";
HTMLEscape_grammar<std::string::const_iterator> l_gramar;
std::string l_ast;
bool result = qi::parse(l_test.begin(), l_test.end(), l_gramar, l_ast);
if (result) {
std::cout << "Parse success\n";
for (unsigned char ch : l_ast)
std::cout << std::setw(2) << std::setfill('0') << std::hex << std::showbase << static_cast<int>(ch) << " ";
} else
{
std::cout << "Parse failure\n";
}
}
版画
Parse success
0x74 0x65 0x73 0x74 0xec 0x8a 0xad 0x61 0x73 0x20 0x74 0x65 0x73 0x74 0x20 0x73 0x69 0x6d 0x70 0x6c 0x65 0xec 0x8a 0xad 0x74 0x65 0x73 0x74