Подтвердить что ты не робот

Извлечение слов из строки, удаление знаков препинания и возврат списка с разделенными словами

Мне было интересно, как реализовать функцию 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']
4b9b3361

Ответ 1

Это не имеет никакого отношения к расщеплению и пунктуации; вам просто нужны буквы (и числа), и просто нужно регулярное выражение:

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'] - это то, что я хочу. существует ли метод без импорта регулярного выражения? Если мы можем просто заменить non ascii_letters на '', то разделив строку на слова в списке, это сработает? - James Smith 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
    ]

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

Ответ 2

Попробуйте использовать 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']

Ответ 3

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