¿Cómo puedo unir caracteres utf8 unicode usando boost::spirit
?Cómo hacer coincidir caracteres unicode con boost :: spirit?
Por ejemplo, quiero reconocer todos los caracteres de esta cadena:
$ echo "На берегу пустынных волн" | ./a.out
Н а б е р е гу п у с т ы н н ы х в о л н
Cuando trato de este sencillo programa boost::spirit
que no coincidirá con los caracteres Unicode correctamente:
#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;
}
se comporta como esto:
$ 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>
ACTUALIZACIÓN:
Bien, trabajé en esto un poco más, y el siguiente código está funcionando. En primer lugar, convierte la entrada en un iterador de caracteres Unicode de 32 bits (como se recomienda 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;
}
El código imprime los puntos de código Unicode:
$ ./a.out
1053 1072 1073 1077 1088 1077 1075 1091 1087 1091 1089 1090 1099 1085 1085 1099 1093 1074 1086 1083 1085
que parece ser correcta, de acuerdo con el oficial Unicode table.
Ahora, ¿alguien puede decirme cómo imprimir los caracteres reales, dado este vector de puntos de código Unicode?
Descubrí que es posible utilizar los iteradores Unicode boost regex, que convierten la entrada utf8 en puntos de código utf32 (http://comments.gmane.org/gmane.comp.parsers.spirit.general/23490), y estoy intentando descubrir cómo funciona ... Se agradece cualquier ayuda. – Frank
Además, los elementos del espacio de nombres 'boost :: spirit :: unicode' se usan aquí (http://boost-spirit.com/dl_more/scheme/scheme_v0.2/sexpr.hpp), pero no sé qué Spirit versión que necesita El mío es de boost 1.49, y no tiene 'boost :: spirit :: unicode'. – Frank
El espacio de nombres boost :: spirit: Unicode se define al establecer la variable BOOST_SPIRIT_UNICODE antes de incluir cualquier archivo de encabezado de Boost :: Spirit: '#define BOOST_SPIRIT_UNICODE' –