Jak mogę dopasować znaki Unicode Utf8 przy użyciu boost::spirit
?Jak dopasować znaki Unicode do boost :: spirit?
Na przykład, chcę rozpoznać wszystkich znaków w tym ciągu:
$ echo "На берегу пустынных волн" | ./a.out
Н а б е р е гу п у с т ы н н ы х в о л н
Kiedy próbuję to proste boost::spirit
programu nie będzie pasować do znaków Unicode poprawnie:
#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;
}
zachowuje się jak to:
$ 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>
AKTUALIZACJA:
OK, trochę nad tym pracowałem, a poniższy kod działa. Najpierw przekształca wejściowej do iteracyjnej 32-bitowych znaków UNICODE (jak zaleca 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;
}
Kod drukuje unikodowym punkty kodowe:
$ ./a.out
1053 1072 1073 1077 1088 1077 1075 1091 1087 1091 1089 1090 1099 1085 1085 1099 1093 1074 1086 1083 1085
, który wydaje się być prawidłowa, według oficjalny Unicode table.
Teraz, czy ktoś może mi powiedzieć, jak wydrukować rzeczywiste znaki zamiast tego wektora punktów kodu Unicode?
Znalazłem, że może to być możliwe za pomocą doładowania unerode regex, które przekształcają dane wejściowe utf8 na punkty kodowe utf32 (http://comments.gmane.org/gmane.comp.parsers.spirit.general/23490), i próbuję dowiedzieć się, jak to działa ... Każda pomoc jest doceniana. – Frank
Stosowane są również elementy z przestrzeni nazw 'boost :: spirit :: unicode' (http://boost-spirit.com/dl_more/scheme/scheme_v0.2/sexpr.hpp), ale nie wiem, co to jest Spirit Wersja tego potrzebuje. Mój jest z boostu 1.49, i nie ma 'boost :: spirit :: unicode'. – Frank
Przypisanie :: spirit: unicode jest zdefiniowane podczas ustawiania zmiennej BOOST_SPIRIT_UNICODE przed dodaniem dowolnego pliku nagłówkowego Boost :: Spirit: '#define BOOST_SPIRIT_UNICODE' –