2009-03-15 7 views
11

Come posso dividere correttamente una stringa contenente una frase con caratteri speciali usando gli spazi bianchi come separatore? Utilizzo del metodo split regolare Non riesco a ottenere il risultato desiderato.python, regex split e carattere speciale

codice Esempio:

# -*- 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 

L'output è:

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 

mentre io sto cercando un output come:

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

da notare che s è una stringa che viene restituito da un altro metodo, quindi non posso forzare la codifica come

s=u"La felicità è tutto" 

Sulla documentazione Python ufficiale di Unicode e reg-ex non ho trovato una spiegazione soddisfacente.

Grazie.

Alessandro

+1

Si sta dividendo su caratteri non di parole, che non include solo spazi, ma anche caratteri (apparentemente) accentati. – mpen

risposta

16

tuo regex dovrebbe essere (\s) invece di (\W) come questo:

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

Il codice di cui sopra vi darà l'output esatto che avete richiesto. Tuttavia la seguente riga ha più senso:

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

che si divide su caratteri di spaziatura e non ti dà tutti gli spazi come partite. Potresti averne bisogno, così ho postato entrambe le risposte.

+0

Grazie, funziona sulla stampa di singole parole. Perché la stampa della lista contiene codice esadecimale unicode invece di caratteri decodificati? – alexroat

+0

È inteso che l'uscita è un codice Python valido che è possibile copiare e incollare nuovamente ... e poiché si potrebbe lavorare in un ambiente non Unicode, esso viene emesso nel modo più portabile possibile. – porges

+0

Grazie Andrew. hai pienamente risposto a tutti i miei dubbi. – alexroat

4

Prova definire una codifica per l'espressione regolare:

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

Non funziona, l'ho già provato ... Tuttavia la soluzione di Andrew Hare funziona bene. – alexroat

+0

Hai provato senza la parentesi? – kgiannakakis

+0

Sì, ma il comportamento è simile alla divisione stringa (rimuove gli spazi bianchi) e desidero mantenerli. Tuttavia, re.UNICODE si confonde con la codifica cambiando alcuni caratteri. – alexroat

3

penso che sia eccessivo per usare un espressione regolare in questo caso. Se l'unica cosa che vuoi fare è dividere la stringa in caratteri di spaziatura mi consiglia di utilizzare il metodo split sulla corda

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

La mia intenzione è di mantenere gli spazi bianchi nell'elenco in modo che lo split string non sia utile per questo perché rimuove gli spazi bianchi e non è completamente configurabile come divisione delle espressioni regolari. – alexroat

+0

@alexroat: Perché hai esattamente bisogno degli spazi? Sai che il verificarsi tra ogni parola (voce dell'elenco), non puoi aggiungere il tuo algoritmo quando necessario? – mpen

0

Bene, dopo alcuni ulteriori test su Andrew Hare risposta che ho visto quel personaggio come () [] - e così via non sono più considerati come separatori mentre voglio dividere una frase (mantenendo tutto il separatore) in parole composte da un insieme di valori alfanumerici impostati alla fine espansi con caratteri accentati (cioè, tutto contrassegnato come alfanumerico in unicode). Quindi, la soluzione di kgiannakakis è più corretta ma manca una conversione di stringhe in formato unicode.

prendere questa estensione del primo esempio:

# -*- 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 

L'output ora è:

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> 

che è esattamente quello che sto cercando.

Saluti :)

Alessandro

3

usando un'espressione regolare unicode funzionerà, purché si dà una stringa unicode per iniziare con (che non avete in l'esempio fornito). Prova questo:

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 

Risultati:

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 

La stringa s è creato come un tipo str, e sarà probabilmente in UTF-8 codifica, che è diverso da quello unicode.