La expresión regular de Python no coincide con un Unicode específico> 2 valores hexadecimales

¿Cómo puedo analizar una ‘cadena’ de Unicode para caracteres mayores que \uFFFF ?

intentó re y regex pero no parece coincidir correctamente con los caracteres Unicode que son mayores que 2 valores hexadecimales.

Tome cualquier cadena Unicode (por ejemplo, un texto de tweet codificado en utf-8 )

 emotes = regex.findall('[\u263A\u263B\u062A\u32E1]',tweet_json_obj['text']) if emotes: print "Happy:{0}".format(len(emotes)) 

La salida es el número de caras sonrientes contenidas en el texto, ¡funciona muy bien!

pero si bash hacer coincidir el conjunto de emoticones de caracteres Unicode: http://www.fileformat.info/info/unicode/block/emoticons/index.htm

 emotes = regex.findall('[\u01F600-\u01F64F]',tweet_json_obj['text']) if emotes: print "Emoticon:{0}".format(len(emotes)) 

output es la coincidencia (número) de todos los caracteres de la cadena, menos los espacios en blanco. ¿Cómo es posible que las expresiones regulares coincidan con todos los caracteres del tweet, o al menos lo que parece ser string.printable?

Los resultados esperados son un retorno de 0 para la mayoría del conjunto de datos, ya que no espero que la gente inserte estos emoticons, pero podrían … así que me gustaría verificar su existencia. ¿Es mi expresión regular incorrecta?

Los puntos de código fuera de BMP usan \Uxxxxxxxx (así que en mayúsculas y 8 caracteres hexadecimales). Está utilizando \uxxxx , que solo toma cuatro caracteres hexadecimales, el 00 no forma parte del punto de código Unicode:

 >>> len(u'\u01f600') 3 >>> len(u'\U0001f600') 1 >>> u'\u01f600'[0] '\u01f6' >>> u'\u01f600'[1:] '00' 

Necesitas usar un patrón de unicode aquí:

 u'[\U0001F600-\U0001F64F]' 

Manifestación:

 >>> import re >>> re.search(u'[\U0001F600-\U0001F64F]', u'\U0001F600') <_sre.SRE_Match object at 0xb73ead08> 

Debe usar una comstackción Python UCS4, de lo contrario, los puntos de código no BMP se implementan utilizando pares sustitutos UTF16, que no funcionarán muy bien con expresiones regulares.

Si len(u'\U0001f600') devuelve 2, en su lugar está utilizando una comstackción UCS2 estrecha, o puede ver sys.maxunicode ; una construcción amplia devuelve 1114111, una construcción estrecha 65535.

En un sistema UCS2, para este caso específico, también podría hacer coincidir los sustitutos de UTF16 con una expresión:

 ur'\ud83d[\ude00-\ude4f]' 

Esto coincide con los pares sustitutos UTF-16 que conforman el mismo rango que [\U0001F600-\U0001F64F] , pero en construcciones estrechas:

 >>> import sys >>> sys.maxunicode 65535 >>> import re >>> re.search(u'\ud83d[\ude00-\ude4f]', u'\U0001F600') <_sre.SRE_Match object at 0x105e9f5e0>