2014-04-26 13 views
5

Używam tokenizera z NLTK w języku Python.Jak usunąć interpunkcję?

Istnieje już cała masa odpowiedzi na usuwanie interpunkcji na forum. Jednak żaden z nich nie rozwiązuje wszystkich poniższych zagadnień razem:

  1. więcej niż jeden symbol w rzędzie. Na przykład zdanie: Powiedział: "to jest to." Ponieważ istnieje przecinek, po którym następuje znak cudzysłowu, tokenizer nie usunie "w zdaniu, a tokenizator poda [" On "," powiedział ",", "", "to", "to", "to". "] zamiast [" On "," powiedział "," to "," s "," to "]. Niektóre inne przykłady to "...", "-", "!?", "," "Itd.
  2. Usuń symbol na końcu zdania. tj. Zdanie: Hello World. Tokenizer poda ['Hello', 'World.'] Zamiast ['Hello', 'World'] Zwróć uwagę na okres na końcu słowa "World". Inne przykłady to "-", ", 'na początku, w środku lub na końcu każdej postaci.
  3. usunąć znaki z symbolami przed i po tj. '*u*', '''','""'

Czy istnieje elegancki sposób rozwiązywania zarówno problemów?

+0

Co masz trudności w realizacji tych wymagań? Jakie masz problemy z aktualną wersją kodu? – jfs

+0

btw, jest wiele pytań, które mają odpowiedzi, które spełniają wszystkie wymagania, np. [Usuń znaki z ciągów sformatowanych w Unicode] (http://stackoverflow.com/q/11066400/4279) – jfs

+0

W jaki sposób odpowiedzi od [Najlepszy sposób na rozbierania się interpunkcja z łańcucha w języku Python] (http://stackoverflow.com/q/265960/4279) zawiedzie Cię? – jfs

Odpowiedz

6

Jeśli chcesz tokenizować swój ciąg w jednym ujęciu, myślę, że twoim jedynym wyborem będzie użycie nltk.tokenize.RegexpTokenizer. Poniższe podejście pozwoli ci na używanie interpunkcji jako znacznika do usuwania znaków alfabetu (jak zaznaczono w trzecim wymaganiu) przed całkowitym usunięciem interpunkcji. Innymi słowy, to podejście usunie *u* przed usunięciem całej interpunkcji.

Jednym ze sposobów, aby przejść na ten temat, a następnie, do tokenize na szczelinach tak:

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

ta powinna spełniać wszystkie trzy kryteria, które zostały określone powyżej. Pamiętaj jednak, że ten tokenizer nie zwróci żetonów, takich jak "A". Co więcej, tylko tokenizuję pojedyncze litery zaczynające się od i z interpunkcją. W przeciwnym razie "Go". nie zwróci tokena. W zależności od tego, jak wyglądają twoje dane i jakie są twoje oczekiwania, możesz potrzebować niszczyć wyrażenie regularne w inny sposób.

+0

Dziękuję za rozwiązanie. Myślę, że tego właśnie szukam. – user3534472

+0

Przepraszam, kliknąłem znacznik wyboru, ale jakoś nie przeszło. – user3534472

+0

@ user3534472 Dzięki! Bez obaw. –

10

Rozwiązanie 1: tokenize i taśmy interpunkcyjny off tokenów

>>> 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'] 

Rozwiązanie 2: usunąć znaki interpunkcyjne następnie 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

Podoba mi się to podejście, ale uważam, że PO jest zawieszony na trzecim wymogu. OP stwierdza, że ​​kod powinien usuwać znaki z "symbolami" przed lub po znakach i podaje jako przykład ''* u *''. Zatem 'u' w takim kontekście powinno zostać usunięte (prawdopodobnie podczas gdy gwiazdki nadal oznaczają, że znak' u' musi iść). –