Извлечение слов из строки, удаление знаков препинания и возврат списка с разделенными словами - PullRequest
16 голосов
/ 03 октября 2011

Мне было интересно, как реализовать функцию get_words(), которая возвращает слова в строке в списке, удаляя пунктуацию.

Как бы я хотел, чтобы это было реализовано, заменить non string.ascii_lettersс '' и возвращает .split().

def get_words(text):

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

    returns text.split()

Например:

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

возвращает:

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

Ответы [ 3 ]

34 голосов
/ 03 октября 2011

Это не имеет ничего общего с расщеплением и пунктуацией;вы просто заботитесь о буквах (и цифрах) и просто хотите использовать регулярное выражение:

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

Демо:

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

Если вам не нужны цифры, замените \w с [A-Za-z] только для букв, или [A-Za-z'] для включения сокращений и т. д. Возможно, есть более причудливые способы включить классы буквенно-нечисловых символов (например, буквы с ударением) в другие регулярные выражения.


Я почти ответил на этот вопрос здесь: Разделить строки с несколькими разделителями?

Но ваш вопрос на самом деле недостаточно конкретизирован: вы хотите, чтобы 'this is: an example' было разделено на:

  • ['this', 'is', 'an', 'example']
  • или ['this', 'is', 'an', '', 'example']?

Я предположил, что это был первый случай.


[this ',' is ',' an ', example'] - это то, что я хочу.Есть ли метод без импорта регулярных выражений?Если бы мы могли просто заменить не ascii_letters на '', то разбить строку на слова в списке, это сработало бы? - Джеймс Смит 2 минуты назад

Регулярное выражение - самое элегантное, но да, вы можете сделать это следующим образом:

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

или .isalpha()


Sidenote: Вы также можете сделать следующее, хотя для этого требуется импортировать другую стандартную библиотеку:

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
    ]

Если это домашнее задание, они, вероятно, ищут императивную вещь, такую ​​как конечный автомат с двумя состояниями, в котором состояние «был последним символом буквы», и если состояние меняетсяиз буквы -> не буквы, то вы выводите слово.Не делай этого;это не хороший способ программирования (хотя иногда абстракция полезна).

11 голосов
/ 03 октября 2011

Попробуйте использовать re:

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

Хотя я не уверен, что он поймает все ваши варианты использования.

Если вы хотите решить это по-другому, вы можете указать символы, которые вы хотите получить в результате:

>>> re.findall('[%s]+' % string.ascii_letters, 'Hello world, my name is...James!')
['Hello', 'world', 'my', 'name', 'is', 'James']
1 голос
/ 03 октября 2011

Все, что вам нужно, это токенизатор. Взгляните на nltk и особенно на WordPunctTokenizer.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...