c++ - 如何将 unicode 字符与 boost::spirit 匹配?

标签 c++ parsing boost boost-spirit

如何使用 boost::spirit 匹配 utf8 unicode 字符?

比如我要识别这个字符串中的所有字符:

$ echo "На берегу пустынных волн" | ./a.out
Н а б е р е гу п у с т ы н н ы х в о л н

当我尝试这个简单的 boost::spirit 程序时,它无法正确匹配 unicode 字符:

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <boost/foreach.hpp>
namespace qi = boost::spirit::qi;

int main() {
  std::cin.unsetf(std::ios::skipws);
  boost::spirit::istream_iterator begin(std::cin);
  boost::spirit::istream_iterator end;

  std::vector<char> letters;
  bool result = qi::phrase_parse(
      begin, end,  // input     
      +qi::char_,  // match every character
      qi::space,   // skip whitespace 
      letters);    // result    

  BOOST_FOREACH(char letter, letters) {
    std::cout << letter << " ";
  }
  std::cout << std::endl;
}

它的行为是这样的:

$ echo "На берегу пустынных волн" | ./a.out | less
<D0> <9D> <D0> <B0> <D0> <B1> <D0> <B5> <D1> <80> <D0> <B5> <D0> <B3> <D1> <83> <D0> <BF> <D1> <83> <D1> <81> <D1> <82> <D1> <8B> <D0> <BD> <D0> <BD> <D1> <8B> <D1> <85> <D0> 
<B2> <D0> <BE> <D0> <BB> <D0> <BD> 

更新:

好的,我在这方面做了更多的工作,下面的代码可以正常工作。它首先将输入转换为 32 位 unicode 字符的迭代器(推荐 here ):

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <boost/foreach.hpp>
#include <boost/regex/pending/unicode_iterator.hpp>
namespace qi = boost::spirit::qi;

int main() {
  std::string str = "На берегу пустынных волн";
  boost::u8_to_u32_iterator<std::string::const_iterator>
      begin(str.begin()), end(str.end());
  typedef boost::uint32_t uchar; // a unicode code point
  std::vector<uchar> letters;
  bool result = qi::phrase_parse(
      begin, end,             // input
      +qi::standard_wide::char_,  // match every character
      qi::space,              // skip whitespace
      letters);               // result
  BOOST_FOREACH(uchar letter, letters) {
    std::cout << letter << " ";
  }
  std::cout << std::endl;
}

代码打印 Unicode 代码点:

$ ./a.out 
1053 1072 1073 1077 1088 1077 1075 1091 1087 1091 1089 1090 1099 1085 1085 1099 1093 1074 1086 1083 1085 

这似乎是正确的,根据官方 Unicode table .

现在,给定这个 Unicode 代码点 vector ,谁能告诉我如何打印实际字符?

最佳答案

我没有太多经验,但显然 Spirit(SVN 主干版本)支持 Unicode。

#define BOOST_SPIRIT_UNICODE // We'll use unicode (UTF8) all throughout

参见,例如<强> sexpr parser sample 在方案演示中。

BOOST_ROOT/libs/spirit/example/scheme

我相信这是基于 Bryce Lelbach1 的演示文稿中的演示,该演示文稿具体展示了:

  • wchar支持
  • utree 属性(实验)
  • s-表达式

有一篇关于S-expressions and variant的在线文章.


1 如果确实如此,这里是 the video from that presentation slides (pdf)发现here (odp)

关于c++ - 如何将 unicode 字符与 boost::spirit 匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10474571/

相关文章:

ssl - Boost SSL 验证过期和自签名证书

c++ - boost::shared_ptr::shared_ptr(const boost::shared_ptr&)' 被隐式声明为已删除

c++ - 在 C++ 中禁用复制省略

c++ - QGraphicsWidget 作为 QObject 的 child

java - 解析文本文件

c++ - 使用 boost::swap 交换原始指针?

C++11 lambda函数对象成员

c++ - 删除是否适用于指向基类的指针?

xml - 使用 xmlpath.v2 golang 获取节点的值

c++ - 如何用直引号C++替换特殊引号