2014-04-26 11 views
5

Sto utilizzando il tokenizer da NLTK in Python.Come rimuovere la punteggiatura?

Ci sono un sacco di risposte per rimuovere le punteggiature sul forum già. Tuttavia, nessuno di loro affrontare tutti i seguenti problemi insieme:

  1. più di un simbolo di fila. Ad esempio, la frase: ha detto "è così". Perché c'è una virgola seguita da virgolette, il tokenizzatore non rimuoverà. "Nella frase, il tokenizzatore darà ['He', 'said', ',' ',' that ',' s ',' it. '] invece di [' He ',' said ',' that ',' s ',' it ']. Alcuni altri esempi includono '...', '-', '!?', ',' ', E così via.
  2. Rimuovi simbolo alla fine della frase. Vale a dire la frase: Hello World. Il tokenizer darà ['Hello', 'World.'] Invece di ['Hello', 'World']. Osserva il punto alla fine della parola 'World'. Alcuni altri esempi includono '-', ', 'all'inizio, al centro o alla fine di ogni carattere.
  3. Rimuovere i caratteri con i simboli di fronte e dopo. es '*u*', '''','""'

c'è un modo elegante di risolvere entrambi i problemi?

+0

Quali difficoltà avete in attuazione di tali requisiti? Quali problemi hai con la tua versione attuale del codice? – jfs

+0

btw, ci sono molte domande che hanno risposte che soddisfano tutti i requisiti, ad esempio, [Rimuovi la punteggiatura da stringhe formattate Unicode] (http://stackoverflow.com/q/11066400/4279) – jfs

+0

Come sono le risposte da [Il modo migliore per cancellare la punteggiatura da una stringa in Python] (http://stackoverflow.com/q/265960/4279) non ti riesce? – jfs

risposta

6

Se si desidera tokenizzare la stringa tutto in una volta, penso che la tua unica scelta sarà quella di utilizzare nltk.tokenize.RegexpTokenizer. Il seguente approccio ti consentirà di usare la punteggiatura come marker per rimuovere i caratteri dell'alfabeto (come indicato nella terza richiesta) prima di rimuovere del tutto la punteggiatura. In altre parole, questo approccio rimuoverà *u* prima di eliminare tutti i segni di punteggiatura.

Un modo per andare su questo, quindi, è quello tokenize sulle lacune in questo modo:

>>> from nltk.tokenize import RegexpTokenizer 
>>> s = '''He said,"that's it." *u* Hello, World.''' 
>>> toker = RegexpTokenizer(r'((?<=[^\w\s])\w(?=[^\w\s])|(\W))+', gaps=True) 
>>> toker.tokenize(s) 
['He', 'said', 'that', 's', 'it', 'Hello', 'World'] # omits *u* per your third requirement 

Questo dovrebbe soddisfare tutti e tre i criteri specificati sopra. Si noti, tuttavia, che questo tokenizer non restituirà token come "A". Inoltre, ho solo tokenize su lettere singole che iniziano con e e terminano con la punteggiatura. Altrimenti, "Vai". non restituirebbe un token. Potrebbe essere necessario sfumare la regex in altri modi, a seconda di come appaiono i tuoi dati e quali sono le tue aspettative.

+0

Grazie per la soluzione. Penso che sia quello che sto cercando. – user3534472

+0

Spiacente, ho fatto clic sul segno di spunta, ma in qualche modo non è andato a buon fine. – user3534472

+0

@ user3534472 Grazie! Nessun problema. –

10

Soluzione 1: Tokenize e nastri di punteggiatura fuori i gettoni

>>> from nltk import word_tokenize 
>>> import string 
>>> punctuations = list(string.punctuation) 
>>> punctuations 
['!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', '{', '|', '}', '~'] 
>>> punctuations.append("''") 
>>> sent = '''He said,"that's it."''' 
>>> word_tokenize(sent) 
['He', 'said', ',', "''", 'that', "'s", 'it', '.', "''"] 
>>> [i for i in word_tokenize(sent) if i not in punctuations] 
['He', 'said', 'that', "'s", 'it'] 
>>> [i.strip("".join(punctuations)) for i in word_tokenize(sent) if i not in punctuations] 
['He', 'said', 'that', 's', 'it'] 

Soluzione 2: rimuovere la punteggiatura poi tokenize

>>> import string 
>>> string.punctuation 
'!"#$%&\'()*+,-./:;<=>[email protected][\\]^_`{|}~' 
>>> sent = '''He said,"that's it."''' 
>>> " ".join("".join([" " if ch in string.punctuation else ch for ch in sent]).split()) 
'He said that s it' 
>>> " ".join("".join([" " if ch in string.punctuation else ch for ch in sent]).split()).split() 
['He', 'said', 'that', 's', 'it'] 
+0

Mi piace questo approccio, ma penso che il PO si stia bloccando sul terzo requisito. L'OP afferma che il codice dovrebbe rimuovere i caratteri con "simboli" prima o dopo i caratteri e fornisce come esempio '' * u * ''. Quindi un 'u' in tale contesto dovrebbe essere rimosso (probabilmente mentre gli asterischi significano ancora che il carattere' u' deve andare). –

Problemi correlati