2012-03-21 10 views
5

Sto provando a dividere una stringa in parole, rimuovendo spazi e segni di punteggiatura.Divisione di una stringa con vari segni di punteggiatura utilizzando split()

Ho provato ad utilizzare il metodo split(), passando tutta la punteggiatura in una volta, ma i miei risultati erano errati:

>>> test='hello,how are you?I am fine,thank you. And you?' 
>>> test.split(' ,.?') 
['hello,how are you?I am fine,thank you. And you?'] 

Io in realtà sanno come fare questo con le regex già, ma mi piacerebbe capire come farlo usando split(). Per favore non darmi una soluzione regex.

+2

Quindi ti ostini a usare una chiave inglese per guidare un chiodo, mentre il martello è a portata di mano. Perché? –

+0

Senza volere mancare di rispetto all'OP penso che dovrebbe esserci un tag per questo tipo di domande in cui lo strumento adeguato viene snobbato per qualsiasi motivo (a volte valido), esse escono di volta in volta. Forse "luddismo"? –

+0

prova C# "Ciao, come stai? Io sto bene, grazie. E tu?". Split (",?.". ToCharArray(), StringSplitOptions.RemoveEmptyEntries); –

risposta

10

questo è il modo migliore che posso pensare senza utilizzare il modulo re:

"".join((char if char.isalpha() else " ") for char in test).split() 
+0

Ooo, questo è un altro modo di farlo, anche se non usa l'elenco esplicito di caratteri divisi ... – larsks

+0

il tuo codice è migliore, può gestire altri segni di punteggiatura – leisurem

+0

Questo è fantastico. Anche se, è un po 'meno efficiente rispetto all'utilizzo di re.split. –

11

Se si desidera dividere una stringa in base a multipla delimitatori, come nel tuo esempio, si sta andando ad avere bisogno di utilizzare il modulo re nonostante i vostri bizzarre obiezioni, in questo modo:

>>> re.split('[?.,]', test) 
['hello', 'how are you', 'I am fine', 'thank you', ' And you', ''] 

E ' possibile per ottenere un risultato simile utilizzando split, ma è necessario chiamare split una volta per ogni carattere, ed è necessario iterare sui risultati della divisione precedente. Questo funziona ma è u-g-l-y:

>>> sum([z.split() 
... for z in sum([y.split('?') 
... for y in sum([x.split('.') 
... for x in test.split(',')],[])], [])], []) 
['hello', 'how', 'are', 'you', 'I', 'am', 'fine', 'thank', 'you', 'And', 'you'] 

questo utilizza sum() per appiattire la lista restituita dalla precedente iterazione.

+0

Si prega di non usare 'sum()' per appiattire gli elenchi di liste - [è lo strumento sbagliato per questo scopo] (http://stackoverflow.com/questions/952914/making-a-flat-list-out- di-lista-dei-liste-in-python/952.952 # 952.952). In questo caso particolare ancora di più, dal momento che una [sola lista di comprensione che utilizza un ciclo annidato] (http://ideone.com/xEXX7) eliminerebbe la necessità di appiattirsi in primo luogo. –

+0

Siete più che benvenuti a pubblicare una soluzione alternativa se ritenete che sia più adatta al problema. – larsks

+0

Fintanto che l'OP non spiega perché 're' non dovrebbe essere usato, non invierò una risposta, poiché non capisco ancora lo scopo della domanda. Il secondo link nel mio ultimo commento mostra una soluzione alternativa, però. –

6

Dal momento che non si desidera utilizzare il modulo re, è possibile utilizzare questo:

test.replace(',',' ').replace('.',' ').replace('?',' ').split() 
+0

test = 'ciao, come stai? Sto bene, grazie. E tu?' for x in prova: se non x.isalpha(): test = test.replace (x,' ') test = test.split test() stampa – leisurem

3

È possibile scrivere una funzione di estendere l'utilizzo di .split():

def multi_split(s, seprators): 
    buf = [s] 
    for sep in seprators: 
     for loop, text in enumerate(buf): 
      buf[loop:loop+1] = [i for i in text.split(sep) if i] 
    return buf 

e provarlo:

>>> multi_split('hello,how are you?I am fine,thank you. And you?', ' ,.?') ['hello', 'how', 'are', 'you', 'I', 'am', 'fine', 'thank', 'you', 'And', 'you']

questo sarà più chiara e può essere utilizzato in altre situazioni.

3

Una versione modificata di risposta larsks', dove non c'è bisogno di digitare tutti i caratteri di punteggiatura te stesso:

import re, string 

re.split("[" + string.punctuation + "]+", test) 
['hello', 'how are you', 'I am fine', 'thank you', ' And you', ''] 
0

Scuse per necroing - questa discussione viene su come primo risultato per la scissione non regex di una frase. Visto che dovevo trovare un metodo non specifico per Python per i miei studenti, e che questa discussione non rispondeva alla mia domanda, pensavo di condividerla per ogni evenienza.

Il punto del codice è quello di non utilizzare le librerie (ed è veloce su file di grandi dimensioni):

sentence = "George Bernard-Shaw was a fine chap, I'm sure - who can really say?" 
alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 
words = [] 
word = "" 
mode = 0 
for ch in sentence: 
    if mode == 1: 
     words.append(word) 
     word = "" 
     mode = 0 
    if ch in alpha or ch == "'" or ch == "-": 
     word += ch 
    else: 
     mode = 1 
words.append(word) 
print(words) 

uscita:

['George', 'Bernard-Shaw', 'was', 'a', 'fine', 'chap', "I'm", 'sure', '-', 'who', 'can', 'really', 'say'] 

ho letteralmente appena scritto questo in circa mezz'ora quindi sono sicuro che la logica potrebbe essere ripulita.Ho anche riconosciuto che potrebbe richiedere una logica aggiuntiva per gestire correttamente avvertenze come i trattini, in quanto il loro uso è incoerente rispetto a qualcosa di simile a una virgola invertita. Esiste un modulo, infatti, che possa farlo correttamente comunque?

Problemi correlati