2011-10-03 15 views
14

Zastanawiam się, jak zaimplementować funkcję get_words(), która zwraca słowa w łańcuchu na liście, usuwając interpunkcję.Wyodrębnianie słów z ciągów znaków, usuwanie interpunkcji i zwracanie listy z oddzielonymi słowami w języku Python

Sposób, w jaki chciałbym go wdrożyć, to zastąpienie non string.ascii_letters przez '' i zwrócenie .split().

def get_words(text): 

    '''The function should take one argument which is a string''' 

    returns text.split() 

Na przykład:

>>>get_words('Hello world, my name is...James!') 

powraca:

>>>['Hello', 'world', 'my', 'name', 'is', 'James'] 
+0

Sformatowałem dla ciebie twoje pytanie. Proszę użyć przycisku 'code' (' {} ') następnym razem. – Johnsyweb

Odpowiedz

1

.All trzeba to tokenizer. Spójrz na nltk, a zwłaszcza na WordPunctTokenizer.

9

Spróbuj użyć re:

>>> [w for w in re.split('\W', 'Hello world, my name is...James!') if w] 
['Hello', 'world', 'my', 'name', 'is', 'James'] 

Chociaż nie jestem pewien, że będzie to nadrobić wszystkie przypadki użycia.

Jeśli chcesz go rozwiązać w inny sposób, można określić znaki, które chcesz mieć w rezultacie:

>>> re.findall('[%s]+' % string.ascii_letters, 'Hello world, my name is...James!') 
['Hello', 'world', 'my', 'name', 'is', 'James'] 
+0

jest sposób na wykonanie tego przy użyciu string.ascii_letters? –

+5

@James Jeśli jest to praca domowa, zaznacz swoje pytanie odpowiednim znacznikiem. –

31

To nie ma nic wspólnego z rozszczepienia i interpunkcji; po prostu dbają o liter (i cyfr), a po prostu wyrażenie regularne:

import re 
def getWords(text): 
    return re.compile('\w+').findall(text) 

Demo:

>>> re.compile('\w+').findall('Hello world, my name is...James the 2nd!') 
['Hello', 'world', 'my', 'name', 'is', 'James', 'the', '2nd'] 

Jeśli nie dbam o liczbach, wymiany \w z [A-Za-z] za jedyne liter lub [A-Za-z'] w celu uwzględnienia skurczów itp. Prawdopodobnie istnieją bardziej eleganckie sposoby dołączania alfabetyczno-nie-numerycznych klas znaków (np. liter z akcentami) do innych wyrażeń regularnych.


prawie odpowiedział na to pytanie tutaj: Split Strings with Multiple Delimiters?

Ale pytanie jest rzeczywiście pod określonym: Chcesz 'this is: an example' być podzielone na:

  • ['this', 'is', 'an', 'example']
  • lub ['this', 'is', 'an', '', 'example']?

Zakładałem, że był to pierwszy przypadek.


[ten 'jest', 'an' Przykład '] jest to, co chcę. czy istnieje metoda bez importowania wyrażenia regularnego? Jeśli możemy po prostu zastąpić non ascii_letters przez "", to czy podział tego słowa na listę? - James Smith 2 minuty temu

RegExp jest najbardziej elegancki, ale tak, można to w następujący sposób:

def getWords(text): 
    """ 
     Returns a list of words, where a word is defined as a 
     maximally connected substring of uppercase or lowercase 
     alphabetic letters, as defined by "a".isalpha() 

     >>> get_words('Hello world, my name is... Élise!') # works in python3 
     ['Hello', 'world', 'my', 'name', 'is', 'Élise'] 
    """ 
    return ''.join((c if c.isalnum() else ' ') for c in text).split() 

lub .isalpha()


Sidenote: Można też wykonaj następujące czynności, chociaż wymaga to zaimportowania innej standardowej biblioteki:

from itertools import * 

# groupby is generally always overkill and makes for unreadable code 
# ... but is fun 

def getWords(text): 
    return [ 
     ''.join(chars) 
      for isWord,chars in 
      groupby(' My name, is test!', lambda c:c.isalnum()) 
      if isWord 
    ] 

Jeśli to praca domowa, prawdopodobnie szukają imperatywnej rzeczy, takiej jak dwustanowa maszyna skończona, gdzie stan to "ostatnia litera jest literą", a jeśli stan zmienia się z litery -> nie -letter, a następnie wypiszesz słowo. Nie rób tego; nie jest to dobry sposób programowania (chociaż czasami abstrakcja jest przydatna).

+0

[to "," jest "," ", przykład"] jest tym, czego chcę. czy istnieje metoda bez importowania wyrażenia regularnego? Jeśli możemy po prostu zastąpić non ascii_letters przez "", to czy podział tego słowa na listę? –

+0

Pracuję nad parsowaniem zbioru danych przemówień, a w słowach tych występują skurcze, tj. 'Jesteśmy' i 'oni są', a użycie twojego wyrażenia regularnego dzieli słowa również' '' znakami. – Peri461

+1

@ Peri461: Dostosowałeś wyrażenie regularne tak, aby zawierało '[\ w ']' zamiast '\ w', tzn." Słowo to jedna lub więcej liter lub apostrofów "zamiast" słowo to jedno lub więcej " listy". – ninjagecko

Powiązane problemy