Разделение строки по различным знакам препинания с использованием split () - PullRequest
6 голосов
/ 21 марта 2012

Я пытаюсь разбить строку на слова, удаляя пробелы и знаки препинания.

Я пытался использовать метод split(), пропуская все знаки пунктуации одновременно, но мои результаты были неверными:

>>> test='hello,how are you?I am fine,thank you. And you?'
>>> test.split(' ,.?')
['hello,how are you?I am fine,thank you. And you?']

На самом деле я уже знаю, как сделать это с помощью регулярных выражений, но я бы хотел выяснить, как это сделать, используя split(). Пожалуйста, не давайте мне решение для регулярных выражений.

Ответы [ 6 ]

13 голосов
/ 21 марта 2012

Если вы хотите разбить строку на основе нескольких разделителей, как в вашем примере, вам понадобится использовать модуль re, несмотря на ваши причудливые возражения, например:

>>> re.split('[?.,]', test)
['hello', 'how are you', 'I am fine', 'thank you', ' And you', '']

возможно получить аналогичный результат, используя split, но вам нужно вызывать split один раз для каждого символа, и вам нужно перебирать результаты предыдущего разделения.Это работает, но уродливо:

>>> sum([z.split() 
... for z in sum([y.split('?') 
... for y in sum([x.split('.') 
... for x in test.split(',')],[])], [])], [])
['hello', 'how', 'are', 'you', 'I', 'am', 'fine', 'thank', 'you', 'And', 'you']

При этом используется sum() для выравнивания списка, возвращенного предыдущей итерацией.

12 голосов
/ 21 марта 2012

Это лучший способ думать без использования модуля re:

"".join((char if char.isalpha() else " ") for char in test).split()
8 голосов
/ 21 марта 2012

Поскольку вы не хотите использовать модуль re, вы можете использовать это:

 test.replace(',',' ').replace('.',' ').replace('?',' ').split()
5 голосов
/ 28 октября 2015

Модифицированная версия ответа жаворонка, в которой вам не нужно вводить все знаки препинания самостоятельно:

import re, string

re.split("[" + string.punctuation + "]+", test)
['hello', 'how are you', 'I am fine', 'thank you', ' And you', '']
3 голосов
/ 21 марта 2012

Вы можете написать функцию для расширения использования .split():

def multi_split(s, seprators):
    buf = [s]
    for sep in seprators:
        for loop, text in enumerate(buf):
            buf[loop:loop+1] = [i for i in text.split(sep) if i]
    return buf

И попробуйте:

>>> multi_split('hello,how are you?I am fine,thank you. And you?', ' ,.?') ['hello', 'how', 'are', 'you', 'I', 'am', 'fine', 'thank', 'you', 'And', 'you']

Это будет более понятным и может быть использовано в других ситуациях.

0 голосов
/ 13 апреля 2016

Извинения за necroing - этот поток появляется как первый результат для расщепления предложения без регулярных выражений. Поскольку я должен был придумать метод, не относящийся к Python, для моих студентов, и что эта ветка не ответила на мой вопрос, я подумал, что поделюсь на всякий случай.

Смысл кода в том, чтобы не использовать библиотеки (и это быстро для больших файлов):

sentence = "George Bernard-Shaw was a fine chap, I'm sure - who can really say?"
alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
words = []
word = ""
mode = 0
for ch in sentence:
    if mode == 1:
        words.append(word)
        word = ""
        mode = 0
    if ch in alpha or ch == "'" or ch == "-":
        word += ch
    else:
        mode = 1
words.append(word)
print(words)

Выход:

['George', 'Bernard-Shaw', 'was', 'a', 'fine', 'chap', "I'm", 'sure', '-', 'who', 'can', 'really', 'say']

Я буквально только что написал это примерно через полчаса, так что я уверен, что логика может быть очищена. Я также признал, что может потребоваться дополнительная логика для правильной обработки предостережений, таких как дефисы, поскольку их использование противоречиво по сравнению с чем-то вроде кавычки. Действительно, есть какой-нибудь модуль, который может делать это правильно?

...