2009-03-15 10 views
11

¿Cómo puedo dividir correctamente una cadena que contiene una oración con caracteres especiales usando espacios en blanco como separador? Utilizando el método de división de expresiones regulares no puedo obtener el resultado deseado.python, regex split y carácter especial

código Ejemplo:

# -*- coding: utf-8 -*- 
import re 


s="La felicità è tutto" # "The happiness is everything" in italian 
l=re.compile("(\W)").split(s) 

print " s> "+s 
print " wordlist> "+str(l) 
for i in l: 
    print " word> "+i 

La salida es:

s> La felicità è tutto 
wordlist> ['La', ' ', 'felicit', '\xc3', '', '\xa0', '', ' ', '', '\xc3', '', '\xa8', '', ' ', 'tutto'] 
word> La 
word> 
word> felicit 
word> Ã 
word> 
word> ? 
word> 
word> 
word> 
word> Ã 
word> 
word> ? 
word> 
word> 
word> tutto 

mientras estoy en busca de una salida como:

s> La felicità è tutto 
wordlist> ['La', ' ', 'felicità', ' ', 'è', ' ', 'tutto'] 
word> La 
word> 
word> felicità 
word> 
word> è 
word> 
word> tutto 

que señalar que s es una cadena que se devuelve desde otro método, por lo que no puedo forzar la codificación como

s=u"La felicità è tutto" 

En la documentación oficial de python de Unicode y reg-ex no he encontrado una explicación satisfactoria.

Gracias.

Alessandro

+1

Se divide en caracteres que no son palabras, que no solo incluyen espacios, sino también (al parecer) caracteres acentuados. – mpen

Respuesta

16

Su expresión regular debe ser (\s) en lugar de (\W) así:

l = re.compile("(\s)").split(s) 

El código anterior le dará la salida exacta solicitada. Sin embargo, la siguiente línea tiene más sentido:

l = re.compile("\s").split(s) 

que se divide en los espacios en blanco y no le da todos los espacios como fósforos. Puede que los necesites, así que publiqué ambas respuestas.

+0

Gracias, funciona en la impresión de palabras sueltas. ¿Por qué la impresión de la lista contiene código hexadecimal Unicode en lugar de caracteres decodificados? – alexroat

+0

Está destinado a ser así, la salida es un código de Python válido que puede copiar y volver a pegar ... y dado que puede estar trabajando en un entorno que no sea Unicode, lo hace de la forma más portátil posible. – porges

+0

Gracias Andrew. respondiste completamente a todas mis dudas. – alexroat

4

Tratar de definir una codificación para la expresión regular:

l=re.compile("\W", re.UNICODE).split(s) 
+0

No funciona, ya lo he intentado ... Sin embargo, la solución de Andrew Hare funciona bien. – alexroat

+0

¿Has probado sin el paréntesis? – kgiannakakis

+0

Sí, pero el comportamiento es como la división de cadena (elimina los espacios en blanco) y quiero mantenerlos. Sin embargo, re.UNICODE se equivocó al codificar cambiando algunos caracteres. – alexroat

3

creo que es una exageración para usar una expresión regular en este caso. Si lo único que quieres hacer es dividir la cadena de caracteres de espacio en blanco le recomiendo usar el método split en la cuerda

s = 'La felicità è tutto' 
words = s.split() 
+0

Mi intención es mantener espacios en blanco en la lista, por lo que la división de cadenas no es útil, ya que elimina los espacios en blanco y no es totalmente configurable como división de expresiones regulares. – alexroat

+0

@alexroat: ¿Por qué exactamente necesitas los espacios? Usted sabe que ocurre entre cada palabra (elemento de la lista), ¿no puede hacer que su algoritmo los vuelva a agregar cuando sea necesario? – mpen

0

Bueno, después de algunas pruebas adicionales sobre la respuesta Andrew Hare He visto que el carácter como () [] - y así sucesivamente ya no se consideran separadores mientras quiero dividir una oración (manteniendo todo el separador) en palabras compuestas con un conjunto de valores alfanuméricos que finalmente se expanden con caracteres acentuados (es decir, todo marcado como alfanumérico en Unicode)) Por lo tanto, la solución de kgiannakakis es más correcta, pero se pierde una conversión de cadena s en formato Unicode.

Tome esta extensión del primer ejemplo:

# -*- coding: utf-8 -*- 
import re 
s="(La felicità è tutto)"#no explicit unicode given string (UTF8) 
l=re.compile("([\W])",re.UNICODE).split(unicode(s,'utf-8'))#split on s converted to unicode from utf8 

print " string> "+s 
print " wordlist> "+str(l) 
for i in l: 
    print " word> "+i 

La salida ahora es:

string> (La felicità è tutto) 
wordlist> [u'', u'(', u'La', u' ', u'felicit\xe0', u' ', u'\xe8', u' ', u'tutto', u')', u''] 
word> 
word> (
word> La 
word> 
word> felicità 
word> 
word> è 
word> 
word> tutto 
word>) 
word> 

eso es exactamente lo que estoy buscando.

Saludos :)

Alessandro

3

usando una expresión regular Unicode funcionará, siempre que darle una cadena Unicode para empezar (que no tiene en el ejemplo dado). Prueba esto:

s=u"La felicità è tutto" # "The happiness is everything" in italian 
l=re.compile("(\W)",re.UNICODE).split(s) 

print " s> "+s 
print " wordlist> "+str(l) 
for i in l: 
    print " word> "+i 

Resultados:

s> La felicità è tutto 
wordlist> [u'La', u' ', u'felicit\xe0', u' ', u'\xe8', u' ', u'tutto'] 
word> La 
word> 
word> felicità 
word> 
word> è 
word> 
word> tutto 

Su cadena s se crea como un tipo str, y probablemente será en la codificación UTF-8, que es diferente de Unicode.

Cuestiones relacionadas