如何使用boost::spirit
來匹配utf8 unicode字符?如何將unicode字符與boost :: spirit匹配?
例如,我想認這個字符串中的所有字符:
$ 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>
UPDATE:
好的,我對此有更多的瞭解,下面的代碼是有用的。它首先將輸入轉換成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代碼點的向量?
我發現它可能使用boost正則表達式unicode迭代器,它將utf8輸入轉換爲utf32代碼點(http://comments.gmane.org/gmane.comp.parsers.spirit.general/23490),我試圖弄清楚這是如何工作的...任何幫助表示讚賞。 – Frank
此外,來自命名空間'boost :: spirit :: unicode'的元素在這裏使用(http://boost-spirit.com/dl_more/scheme/scheme_v0.2/sexpr.hpp),但我不知道什麼是Spirit這需要版本。礦井來自boost 1.49,它沒有'boost :: spirit :: unicode'。 – Frank
boost :: spirit:unicode命名空間是在包含任何Boost :: Spirit頭文件之前設置BOOST_SPIRIT_UNICODE變量時定義的: '#define BOOST_SPIRIT_UNICODE' –